Java represents float and double values according to the IEEE 754-1985 standard. This standard requires that values are broken into component fields of sign, exponent and mantissa. The exponential base is 2. Usage of a base 2 (binary) representation is more computationally efficient than usage of base 10 (decimal). But this requires that decimal numbers be expressed as binary exponential values. It is not possible to do this with complete precision except in cases where the decimal number is itself some power of 2. Consider these examples:
2 ^ -4 = 0.0625
2 ^ -3 = 0.125
2 ^ -2 = 0.025
2 ^ -1 = 0.5
2 ^ 0 = 1.0
2 ^ 1 = 2.0
2 ^ 2 = 4.0
Clearly these decimal values can be represented exactly because they correspond directly to some binary exponential value. Not all decimal numbers can be represented accurately with finite precision. Your decimal value 1.01 is actually represented in IEEE 754 single-precision (32-bit) format as the hexadecimal value '41226666'. This corresponds to a sign bit of '0', an exponent of '01111111' (decimal 127), and a mantissa of '00000010100011110101110' (decimal 1.0099999). To get the true value of the exponent, you must subtract the 'bias' which is 127 for single-precision format. Values > 127 are considered positive exponents and values < 127 are negative exponents. So, in actuality, the value of 10.15 is represented as:
1.0099999 * 2 ^ 0 = 1.0099999
The double precision value is similar, although my experience has been that it is sometimes a more faithful representation.
In the end, this representation results in values that are but an _approximation_ of the actual decimal value. If you want/need to represent decimal numbers with arbitrary precision _exactly_ in Java, you should not use the float/double primitives. Instead, use the BigDecimal class. That is precisely the purpose for which it is intended. FYI, the folks at IBM think that there are some improvement that should be made in BigDecimal. They've developed a new BigDecimal class which addresses their issues and submitted a change proposal to the Java Community Process. You can get the improved implementation (which someday may be part of the JDK) at
http://www.alphaworks.ibm.
For more information than you'll ever want to know about floating-point representation, consider visiting these links:
http://www.research.micros
http://www.dca.fee.unicamp
Best regards,
Jim Cakalic
Main Topics
Browse All Topics





by: javabitPosted on 2000-11-17 at 19:23:13ID: 5429286
Hi hjack,
eValue();
ethod: "+dd);
I found out that parseDouble is a methodfrom java2, not supported in e.g. 1.1.6.
I tried to simulate your prob with the code :
for(i=0;i<100;i++)
{
d = Double.valueOf(""+i).doubl
d+=d;
System.out.println("wel: "+d);
}
for(k=0;k<100;k++)
{
dd = Double.parseDouble(""+k);
dd+=dd;
System.out.println("parsem
}
Hoping to find a difference between your parseDouble and the older valueOf.
Nevertheless, I don't get any .3.010000000000005... differences, so I would say :
who is causing this 3.010000000000005...
maybe has to be found in the variables :
result
or
values[i]
In order to check this, we need more coding from your part.
I also rememver my old pocketcalculator that from time to time
said that 2+2=4.000001, due to the way numbers are stored. When 2 and 2 are e.g. int's, you wont have this problem.
cheers,
javabit