Why substraction problems for 'double' variables ?
I'm a newby in the Java world and I would appreciate very much if anyone could help me by providing me a detailed explanation / solution to my problem.
I declared as double a variable and did the following substraction:
myVariable = myVariable - 0.01
several times till a condition was fulfilled.
There were possible 100 values for my variable, from 100% (meaning 1) down to 1% (meaning 0.01), using a step of 1%.
In my case integer values couldn't be used, being mandatory to use so the step of 0.01 and not the step of 1.
I initialised so the variable to 1 and was surprised to discover that after 7 substraction steps, instead of having 0.93 i got 0.92999...
It was like 0.94 -0.01 = 0.92999..., a behaviour which seems weird to me.
Why that bug (at least I see it as a bug)?
To get rid of the problem I set the variable to float.
However, I don't get a clean set of those 100 values, even though the first 2 decimals are correct when using the float, there are still digits different than zero afterwards.
Is there a clean solution for my design to get only those 100 values:
1, 0.99, 0.98, ..., 0.02, 0.01?
Thanks a lot for your help.
[1227 byte] By [
jon_winea] at [2007-10-1 2:02:58]

> Is there a clean solution for my design to get only those 100 values:
1, 0.99, 0.98, ..., 0.02, 0.01?
Either
1) Use the BigDecimal class, not doubles or floats, or
2) Check the result of the subtraction; if it's sufficiently close to zero - you decide what's "sufficiently close" - then replace the result with zero. Then use the result as you normally would.
The cause:
Binary double and float values have a limited number of bits (1's and 0's) with which they represent base-10 decimals. Not every base-10 decimal number can be exactly represented (certain ones require an infinite number of bits!), so they are approximated. This is a "feature" of all binary floating point numbers. BigDecimal does it differently, base-10 decimals are exact.
Here is a pretty good explanation with lots of detail:
http://www.math.grin.edu/~stone/courses/fundamentals/IEEE-reals.html
Hello,
what you could do is, do the integer math, then run a shift of the decimal on the result. It is overkill, but there is no rounding needed. You do have 3 new objects (String (2), StringBuffer (1), Double (0, static call)) to play with. An example:
String shift = "00";
double d = 100.0;
d = d - 1.0;
String s = String.valueOf(d);
int i = s.indexOf(".");
StringBuffer sb = new StringBuffer(shift + s);
sb.deleteCharAt(i + shift.length());
sb.insert(i, ".");
double dd = Double.parseDouble(sb.toString());