Adding two float values got strange result

Discussion in 'Java' started by Pietro Marrone, Apr 17, 2007.

  1. 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, Apr 17, 2007
    #1
    1. Advertising

  2. Pietro Marrone

    Chris Dollin Guest

    Pietro Marrone wrote:

    > On 17 Apr, 11:50, Pietro Marrone <> wrote:
    >> 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?


    Floating. Point. Numbers. Have. Limited. Precision. And. Are. Not.
    Stored. As. Decimal. Values.

    --
    "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
    Chris Dollin, Apr 17, 2007
    #2
    1. Advertising

  3. On 17 Apr, 11:50, Pietro Marrone <> wrote:
    > 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


    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
    Pietro Marrone, Apr 17, 2007
    #3
  4. On 17 Apr, 11:50, Pietro Marrone <> wrote:
    > 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


    It works if I declare primitive types as double.
    iis it a strange causality or is a rule?

    Regards
    Pietro Marrone, Apr 17, 2007
    #4
  5. Pietro Marrone wrote:
    ..
    >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


    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)?

    --
    Andrew Thompson
    http://www.athompson.info/andrew/

    Message posted via http://www.javakb.com
    Andrew Thompson, Apr 17, 2007
    #5
  6. Pietro Marrone wrote:
    > 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


    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
    Patricia Shanahan, Apr 17, 2007
    #6
  7. Pietro Marrone wrote:
    > On 17 Apr, 11:50, Pietro Marrone <> wrote:
    >> 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

    >
    > 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.


    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
    Patricia Shanahan, Apr 17, 2007
    #7
  8. Pietro Marrone

    Lew Guest

    Pietro Marrone wrote:
    >>> 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?


    Chris Dollin wrote:
    > 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>

    --
    Lew
    Lew, Apr 17, 2007
    #8
  9. Pietro Marrone

    Chris Dollin Guest

    Lew wrote:

    > Chris Dollin wrote:
    >> 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.

    --
    "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
    Chris Dollin, Apr 17, 2007
    #9
  10. Pietro Marrone wrote:
    > On 17 Apr, 11:50, Pietro Marrone <> wrote:
    >> 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

    >
    > It works if I declare primitive types as double.
    > iis it a strange causality or is a rule?
    >
    > 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
    Patricia Shanahan, Apr 17, 2007
    #10
  11. Lew wrote:
    > 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...
    Joshua Cranmer, Apr 17, 2007
    #11
  12. Pietro Marrone wrote:
    > On 17 Apr, 11:50, Pietro Marrone <> wrote:
    >> 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

    >
    > 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.

    --
    John W. Kennedy
    Read the remains of Shakespeare's lost play, now annotated!
    http://pws.prserv.net/jwkennedy/Double Falshood/index.html
    * TagZilla 0.066 * http://tagzilla.mozdev.org
    John W. Kennedy, Apr 17, 2007
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bd
    Replies:
    0
    Views:
    605
  2. k3n3dy
    Replies:
    15
    Views:
    973
    dan2online
    Apr 20, 2006
  3. Carsten Fuchs
    Replies:
    45
    Views:
    1,505
    James Kanze
    Oct 8, 2009
  4. Michael Tan
    Replies:
    32
    Views:
    930
    Ara.T.Howard
    Jul 21, 2005
  5. Joey Zhou
    Replies:
    5
    Views:
    229
    Joey Zhou
    Apr 15, 2011
Loading...

Share This Page