Java Forum / General / April 2007
Adding two float values got strange result
Pietro Marrone - 17 Apr 2007 10:50 GMT Hi, thie is my simple test case:
public class Main {
public static void main(String[] args) { float a = 123.76f; float b = 52.0f;
System.out.println(a + b); System.out.println((float) a + b); System.out.println((float) a + (float) b); System.out.println((float) (a + b)); } }
The results for all four System.out is the same, guess what?: 175.01001
Cuold anyone explein me why, at least a refer to rules explaining what happens?
Regards
Pietro Marrone - 17 Apr 2007 11:13 GMT > Hi, thie is my simple test case: > [quoted text clipped - 19 lines] > > Regards Another wrong test case: package it.test;
public class Main {
public static void main(String[] args) { float a = (float)123.76; float b = (float)52.0;
System.out.println(a + b); System.out.println((float) a + b); System.out.println((float) a + (float) b); System.out.println((float) (a + b)); } }
gives 175.76001, but unfortunetly neither this result is correct.
My JRE version is: java version "1.5.0_11" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03) Java HotSpot(TM) Client VM (build 1.5.0_11-b03, mixed mode)
My OS is: Windows XP Professional Version 2002 SP2
My Hardware is: AMD Athlon 64 Processor 3500+
Regards
Chris Dollin - 17 Apr 2007 11:09 GMT >> Hi, thie is my simple test case: >> [quoted text clipped - 17 lines] >> Cuold anyone explein me why, at least a refer to rules explaining what >> happens? Floating. Point. Numbers. Have. Limited. Precision. And. Are. Not. Stored. As. Decimal. Values.
 Signature "Possibly you're not recalling some of his previous plans." Zoe, /Firefly/
Hewlett-Packard Limited Cain Road, Bracknell, registered no: registered office: Berks RG12 1HN 690597 England
Lew - 17 Apr 2007 13:15 GMT Pietro Marrone wrote:
>>> public class Main { >>> [quoted text clipped - 15 lines] >>> Cuold anyone explein me why, at least a refer to rules explaining what >>> happens?
> Floating. Point. Numbers. Have. Limited. Precision. And. Are. Not. > Stored. As. Decimal. Values. Why isn't numerical analysis part of developer training?
To the OP: <http://developers.sun.com/sunstudio/numerics_index.html>
In particular: <http://docs.sun.com/source/817-6702/ncg_goldberg.html>
 Signature Lew
Chris Dollin - 17 Apr 2007 13:39 GMT >> Floating. Point. Numbers. Have. Limited. Precision. And. Are. Not. >> Stored. As. Decimal. Values. > > Why isn't numerical analysis part of developer training? Because it's a horribly complex and detailed subject, most of which is irrelevant to most of what most developers do.
Some /basic awareness/ of the floaty bits of floating point should be grafted into the brain of a putative developer, mind.
 Signature "It took a very long time, much longer than the most /Sector General/ generous estimates." - James White
Hewlett-Packard Limited registered office: Cain Road, Bracknell, registered no: 690597 England Berks RG12 1HN
Joshua Cranmer - 17 Apr 2007 22:24 GMT > Why isn't numerical analysis part of developer training? It used to be, back when CS was part of "Applied Mathematics." It also doesn't help that it is pushed back until late in the mathematics track: I'm taking it next year, *after* Multivariable Calculus and Linear Algebra...
Patricia Shanahan - 17 Apr 2007 12:11 GMT >> Hi, thie is my simple test case: >> [quoted text clipped - 37 lines] > > gives 175.76001, but unfortunetly neither this result is correct. The result you report for this program matches the answer Andrew and I got for the first program.
Java float and double each represent numbers in binary floating point. Java float has, effectively, 24 significant bits, the equivalent of about 7.2 decimal digits. You should expect rounding error in the 8th significant decimal digit.
The rules are in the JLS, see http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 the following section, and the sections they reference.
IEEE 32 bit float is almost always the wrong data type to use. It gives up a lot of accuracy for halving the space required compared to double. If you should be using a binary floating point type at all, you should normally use double. The exception is if you are storing a large number of values with low accuracy requirements, and have done the numerical analysis to convince yourself that float is precise enough.
If you need the behavior you seem to expect, exact representation and addition of decimal fractions, consider using BigDecimal.
Patricia
Pietro Marrone - 17 Apr 2007 11:16 GMT > Hi, thie is my simple test case: > [quoted text clipped - 19 lines] > > Regards It works if I declare primitive types as double. iis it a strange causality or is a rule?
Regards
Patricia Shanahan - 17 Apr 2007 15:10 GMT >> Hi, thie is my simple test case: >> [quoted text clipped - 24 lines] > > Regards As a general rule, double gives a lot more precision than float, 53 significant bits instead of 24. However, the default Double.toString conversion always produces enough decimal places to uniquely identify the double value, so it can produce similar effects, just with longer output. Of course, all of this is very dependent on the particular numbers you pick.
If you strongly favor exact processing of decimal fractions, you should use neither double nor float, but BigDecimal which is designed for that job.
Patricia
John W. Kennedy - 17 Apr 2007 23:05 GMT >> Hi, thie is my simple test case: >> [quoted text clipped - 22 lines] > It works if I declare primitive types as double. > iis it a strange causality or is a rule? It "works" with float, too. It just doesn't work in the way that you expect it to.
Computers use binary arithmetic. Some computers have used binary arithmetic since the early 1950s, and nearly all computers have used binary arithmetic since the mid 1960s. If you have taken any kind of computer programming course at all, you should bring a lawsuit against the fool of a teacher who did not instruct you in this.
Do you remember how, with decimal fractions, you discovered that 1/3 + 1/3 + 1/3 added up to 0.99 instead of 1? Well, with binary fractions, you have the same problem where 1/10 or 1/100 is involved. But for purposes of science and engineering, binary arithmetic is just as effective as decimal arithmetic, and faster and cheaper. The world is not carved up into exact decimal fractions. Distances between points are not always an exact number of millimeters. Masses of objects are not always an exact number of grams. Time intervals are not always an exact number of milliseconds.
Money, on the other hand, /is/ carved up into exact decimal fractions. Therefore, when you are working with money, you should use the Java BigDecimal class, instead of float or double. Dollars are always an exact number of cents. Euros are always an exact number of eurocents. Pounds are always an exact number of new pence. The considerable loss of time involved in using BigDecimal is unimportant, because the calculations involving money are far less intensive than the complex problems in calculus that come up in science and engineering.
 Signature John W. Kennedy Read the remains of Shakespeare's lost play, now annotated! http://pws.prserv.net/jwkennedy/Double%20Falshood/index.html * TagZilla 0.066 * http://tagzilla.mozdev.org
Andrew Thompson - 17 Apr 2007 11:23 GMT ..
>public class Main { > [quoted text clipped - 11 lines] >The results for all four System.out is the same, guess what?: >175.01001 The results I get here are..
175.76001 175.76001 175.76001 175.76001
>Cuold anyone explein me why, at least a refer to rules explaining what >happens? Buggy implementation? Check the launch files here (not the screenshot on the right). <http://www.physci.org/jws/#jtest> ..what is your java.vm.version (1.6.0-b105 in the screenshot)?
 Signature Andrew Thompson http://www.athompson.info/andrew/
Patricia Shanahan - 17 Apr 2007 11:57 GMT > Hi, thie is my simple test case: > [quoted text clipped - 13 lines] > The results for all four System.out is the same, guess what?: > 175.01001 Are you absolutely sure the program you posted got that result?
I ran it with result:
175.76001 175.76001 175.76001 175.76001
which is the same as Andrew got. All Java implementations should get the same answer for the posted program.
Patricia
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|