Sign in to follow this  
squicklid

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

Recommended Posts

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 this post


Link to post
Share on other sites
Quote:

.7 * 3 = ~2.1
.3 * 3 = ~0.9
~2.1 + ~0.9 = 2.99999
int(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 this post


Link to post
Share on other sites
Quote:
Original post by keen
.7*3 equals exactly 2.1
and .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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by _DarkWIng_
Quote:
Original post by keen
.7*3 equals exactly 2.1
and .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 this post


Link to post
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 this post


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

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Eelco
the 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by civguy
Quote:
Original post by Eelco
the 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by MichaelT
Quote:
Original post by MaulingMonkey
WRONG 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 this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this