# int s = (.7 * 3) + (.3 * 3) is 2 ?

This topic is 4869 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I can't figure this out. I think it is from roundoff error, but I don't know how to correct it.

##### Share on other sites
squicklid: I conqur.

By default I believe float to int conversion rounds down.

Therefore, you probably want "round to nearest" instead. Just add 0.5 to the end of the equasion, and you'll be set.

-Mike

##### Share on other sites
thanks. that works

-Garrett(Squicklid)

##### Share on other sites
Quote:
 Original post by MichaelT.7 * 3 = 2.1.3 * 3 = 0.9(int)2.1 = 2;(int)0.9 = 0;2 + 0 = 2;

WRONG order of operations for his statement, sorry.

(.7 * 3) gets treated as a float or double (froget which by default).

Next, (.3 * 3) is evaluated (also float or double).

Then, addition is preformed. If (.3 * 3) had been an int, it would be implicitly cast to float. (float * int = float, int * float = int).

What's happening is:

.7 * 3 = ~2.1
.3 * 3 = ~0.9
~2.1 + ~0.9 = 2.99999
int(2.999999) = 2

##### Share on other sites
MaulingMonkey is right. [wink]

##### Share on other sites
..thanks.. got it.

##### Share on other sites
Quote:
 .7 * 3 = ~2.1.3 * 3 = ~0.9~2.1 + ~0.9 = 2.99999int(2.999999) = 2

.7*3 equals exactly 2.1
and .3 *3 = exactly 0.9
so 2.1+0.9=3 so that's cant be the case

##### Share on other sites
Quote:
 Original post by keen.7*3 equals exactly 2.1and .3 *3 = exactly 0.9

Nothing is 'exactly' in floating point math. If you want to write 0.9 exacly in FP mathy you need 'exactly' infinite digits. [grin]

##### Share on other sites
int main(){  int a,b;  float c;  a=(.7 * 3) + (.3 * 3);  b=((float)(.7 * 3)) + ((float)(.3 * 3));  c=(.7 * 3) + (.3 * 3);  printf("%i,%i,%f\n",a,b,c);}

output: 2,3,3.000000

proves my point

##### Share on other sites
Quote:
Original post by _DarkWIng_
Quote:
 Original post by keen.7*3 equals exactly 2.1and .3 *3 = exactly 0.9

Nothing is 'exactly' in floating point math. If you want to write 0.9 exacly in FP mathy you need 'exactly' infinite digits. [grin]

But those numbers are doubles, not floats. I agree with MichaelT on this one.

/MindWipe

##### Share on other sites
keen, you're wrong, since .3 * 3 and .7 * 3 (- respectively 0.9 and 2.1) are having roundoff erros when saved in the binary system - both are periodic fractions.
Thus it can happen that its not 3 but e.g. 2.9999.

##### Share on other sites
ok, you convinced me ;)
it was easy to try out with .7*4 since that would have yieled the same values if it was in that way

##### Share on other sites
but
int main(){  int a,b;  float c;  a=((float)(.7 * 3)) + ((float)(.3 * 3));  b=((double)(.7 * 3)) + ((double)(.3 * 3));  c=(.7 * 3) + (.3 * 3);  printf("%i,%i,%f\n",a,b,c);}

gives
3,2,3.000000
so it's roundoff errors in double and not float that makes it

##### Share on other sites
welcome to the world of misterious float-to-int casts...

and in more relevant, it's rounded in pretty random ways,and you should always expect that casting of nearly-integer valued floats to ints gives very undefined results.
Even if you do
int a=3.0;
int b=4.0;
int c=5.0;
etc.
some will round down..

##### Share on other sites
the problem is flats cant really take most values. a float can be exactly 1, exactly 2, but not exactly 3, for example.

and values printed by printf are rounded down to some degree, so they are not an accurate representation of the actual number contained in the float. when it prints 3.000000, it might well actually be 2.9999999.

2^23 is 8388608, almost 8 digits of accuracy, whereas the printf representation only returns 7. printf cant print the last digit, because it cant be sure what value it really represents.

##### Share on other sites
Why can't a float be exactly 3? It would seem that the precision bits could easilly hold 11000... with an exponent of ...0001, exactly representing 1.5 * 2^1 = 3. (Yes, I know there is an implied bit and a bias, but those have been left out for clarity's sake)

##### Share on other sites
Quote:
 Original post by Eelcothe problem is flats cant really take most values. a float can be exactly 1, exactly 2, but not exactly 3, for example.
Floats can be exactly 3 as well. Floats can represent all whole numbers exactly as long as the number is small enough to fit in the mantissa.

##### Share on other sites
Is this not why we put "f" after floating point numbers? Does that make it exactly the number you hard-code?

##### Share on other sites
No. The 'f' in 3.0f stands for float. If you omit it (3.0) then you create a double constant.

##### Share on other sites
Quote:
 Nothing is 'exactly' in floating point math. If you want to write 0.9 exacly in FP mathy you need 'exactly' infinite digits

I dont understand why this is the case for rational numbers.
If it was an irrational number, then I see why you would need
"exactly infinite digits".

- prowst

##### Share on other sites
int main(){  int a=3;  float b=.7f*3+0.3f*3;  double c=.7*3+0.3*3;  printf("%i %i %i\n",a,(int)b,(int)c);  printf("%i %.30f %.30f\n",a,b,c);}

gives
3 3 2
3 3.000000000000000000000000000000 2.999999999999999555910790149937

which is exactly what MaulingMonkey said

##### Share on other sites
Quote:
Original post by civguy
Quote:
 Original post by Eelcothe problem is flats cant really take most values. a float can be exactly 1, exactly 2, but not exactly 3, for example.
Floats can be exactly 3 as well. Floats can represent all whole numbers exactly as long as the number is small enough to fit in the mantissa.

yeah youre right.

my tests show that 2.1 + 0.9 (making sure the compiler cant add them at compiletime) does exactly yield the same bitpattern as a constant float with value 3. it cant be an inaccuracy in the adding, so it must be a rounding quirck then.

##### Share on other sites
@keen

I copied your code as written and compiled it, and my results were:

3 3 2
3 3.000000000000000000000000000000 2.999999999999999600000000000000

Does it depend on the fpu, compiler, sdks, OS, etc?
Why would mine display different results?

- prowst

##### Share on other sites
Quote:
Original post by prowst
Quote:
 Nothing is 'exactly' in floating point math. If you want to write 0.9 exacly in FP mathy you need 'exactly' infinite digits

I dont understand why this is the case for rational numbers.
If it was an irrational number, then I see why you would need
"exactly infinite digits".

- prowst

Rational means that a number can be expressed as the ratio of two whole numbers, but that's simply not how computers store numbers. Rational numbers can also have infinitely-repeating digits in decimal (e.g. 1/3; rational but takes an infinite number of digits in base-10 to express).

.9 can be represented as a single-digit number in a decimal numbering system where each digit is the coefficient of the place:
...00.900...
= ...0*10^1 + 0*10^0 + 9*10^-1 + 0*10^-2 + 0*10^-3...
= ...0*10 + 0*1 + 9*.1 + 0*.01 + 0*.001...
You can represent any number in decimal without repeating digits if it can be expressed a sum of powers of 10.

Since computers store numbers in binary, you're only going to have a finite number of non-zero digits if it exactly fits with the binary coefficients:
...ab.cd...
= ...a*2^1 + b*2^0 + c*2^-1 + d*2^-2...
= ...a*2 + b*1 + c*.5 + d*.25

Where the coefficients are either 0 or 1. Try working out .9 and you'll find you go on forever.

In summation, you can only represent a number in floating point exactly if it can be represented as a sum of powers of two. .9 is not such a number, but all whole numbers are.

##### Share on other sites
Quote:
Original post by MichaelT
Quote:
 Original post by MaulingMonkeyWRONG order of operations for his statement, sorry.

Handling them like that works just as well for that particular problem.

In your exmaple you're implying a different order of operations than is occuring, by using his equasion and then suddenly going off on a tangent doing your own thing instead of the same thing as the main equasion.

It does NOT work "just as well" as it fails to explain how a compiler determines this case usually. It has potential to confuse any newbies who read the topic, which is the reason I'm now quite annoyed that you appear to be trying to defend your example.

##### Share on other sites

This topic is 4869 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.