numeric issue: 0.95 - 0.05 == 0.8499996

M

Maciej

Why ?

Precisely I proceede as follows:

float e = 1.0f;

e -= 0.05f;
e -= 0.05f;

what gives me:

e == 0.84999996

not expected:

e == 0.85

?

The same is for double type. What is the reason for that ?

TIA

Maciej
 
P

Philipp Taprogge

Hi!

Thus spake Maciej on 05/10/2007 12:46 AM:
Why ?

Precisely I proceede as follows:

float e = 1.0f;

e -= 0.05f;
e -= 0.05f;

what gives me:

e == 0.84999996

What is exactly what one would expect.
The same is for double type. What is the reason for that ?

The reason is simply that most floats cannot be precisely
represented as binary floats. They will always be represented by the
nearest float that can.
Floating point operations on binary hardware are always approximations.
If you need precision, use integer arithmetics.

Regards,

Phil
 
K

~kurt

Maciej said:

The short answer is what Phil said.

The long answer:

Precisely I proceede as follows:

float e = 1.0f;

e -= 0.05f;
e -= 0.05f;

If you are in a loop, where you will be increasing or decreasing a
number by a fixed step size, a better method is to retain the initial
number (e0 = 1.0), and the number of iterations (n = 2), and subtract the step
size (delta = 0.05) times the number of iterations from the original number:

e = e0 - n*delta;

Instead of

e -= delta;

You will still have truncation error, but it will not be cumulative - you
start off fresh with each iteration.

- Kurt
 
C

Christian

Philipp said:
Hi!

Thus spake Maciej on 05/10/2007 12:46 AM:

What is exactly what one would expect.


The reason is simply that most floats cannot be precisely
represented as binary floats. They will always be represented by the
nearest float that can.
Floating point operations on binary hardware are always approximations.
If you need precision, use integer arithmetics.

Regards,

Phil
but around 1 the precision of floats should be much higher .. I could
understand this "mistake" if he subtracted 3 times 0.05f
 
J

John W. Kennedy

Maciej said:
Why ?

Precisely I proceede as follows:

float e = 1.0f;

e -= 0.05f;
e -= 0.05f;

what gives me:

e == 0.84999996

not expected:

e == 0.85

?

The same is for double type. What is the reason for that ?

The reason is that your teacher is incompetent. You should sue for fraud
and breach of contract.

If you are not learning from a teacher, your textbook is incompetently
written. Burn it and get another.

--
John W. Kennedy
"I want everybody to be smart. As smart as they can be. A world of
ignorant people is too dangerous to live in."
-- Garson Kanin. "Born Yesterday"
* TagZilla 0.066 * http://tagzilla.mozdev.org
 
P

Patricia Shanahan

Christian said:
but around 1 the precision of floats should be much higher .. I could
understand this "mistake" if he subtracted 3 times 0.05f

The OP expected "e == 0.85", so presumably the intent was to subtract
0.05 three times, and the difference is normal rounding error.

Patricia
 
K

~kurt

Christian said:
but around 1 the precision of floats should be much higher .. I could
understand this "mistake" if he subtracted 3 times 0.05f

This is about the inability to accurately represent decimal numbers
in binary format. 8/9 is close to 1 - not a large or small number.
But, you can not represent it in decimal format with a finite number
of digits. In the same way, you can not represent various finite decimal
numbers in binary with a finite number of 1's and 0's.

- Kurt
 
A

Andreas Leitgeb

Maciej said:
Why ?
Precisely I proceede as follows:
float e = 1.0f;
e -= 0.05f;
e -= 0.05f;
what gives me:
e == 0.84999996
not expected:
e == 0.85

If it weren't for machine arithmetics, I'd have expected 0.9,
not 0.85 , after subtracting twice 0.05 from 1.0 :)

Anyway, if you always subtract steps of 0.05, you had better
start with an int e=100; and subtract 5 from that.
where you need the floating point value, you just divide
e/100.0 ( don't forget the .0 to 100, or you'll get integer
division)
 
C

Christian

~kurt said:
This is about the inability to accurately represent decimal numbers
in binary format. 8/9 is close to 1 - not a large or small number.
But, you can not represent it in decimal format with a finite number
of digits. In the same way, you can not represent various finite decimal
numbers in binary with a finite number of 1's and 0's.

- Kurt
I know how floats work...

thats why i said the precision should be higher.. not that it has to be
0.9f..
in fact if I print out 1f-0.05f-0.05f it is exactly 0.9f

while 1f-0.05f-0.05f-0.05f is 0.84999996 what is ok and in the range of
the expected precision.. but a twentyth mistake on calculations between
-1 and 1 should be much harder to achieve...
 
P

Patricia Shanahan

Christian said:
I know how floats work...

thats why i said the precision should be higher.. not that it has to be
0.9f..
in fact if I print out 1f-0.05f-0.05f it is exactly 0.9f

while 1f-0.05f-0.05f-0.05f is 0.84999996 what is ok and in the range of
the expected precision.. but a twentyth mistake on calculations between
-1 and 1 should be much harder to achieve...

The expected answer in the original message was 0.85, so I think we
should assume the subtraction was done three times, and the only issue
is normal rounding error.

Patricia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top