BigDecimal(String) vs. BigDecimal(double) [Floating-point arithmetics]

Discussion in 'Java' started by Stanimir Stamenkov, Jul 17, 2008.

  1. I've observed depending on whether a BigDecimal is constructed with
    a String or double representing the same value, I get different
    results in a rounding operation:

    import java.math.BigDecimal;
    import java.math.RoundingMode;
    public class FPTest {
    public static void main(String[] args) {
    double a = 3.1231215;
    BigDecimal b = new BigDecimal(a);
    BigDecimal c = new BigDecimal(Double.toString(a));
    System.out.println(b.setScale(6, RoundingMode.HALF_UP));
    System.out.println(c.setScale(6, RoundingMode.HALF_UP));
    }
    }

    The output I get is:

    3.123121
    3.123122

    How are the two constructors BigDecimal(String) and
    BigDecimal(double) different?

    --
    Stanimir
    Stanimir Stamenkov, Jul 17, 2008
    #1
    1. Advertising

  2. Stanimir Stamenkov

    Stefan Ram Guest

    Stanimir Stamenkov <> writes:
    >How are the two constructors BigDecimal(String) and
    >BigDecimal(double) different?


    Decimal fractions often are not represented precisely by
    double, and java.lang.Double#toString(double) will often not
    create the exact decimal representation of the binary fraction
    corresponding to the double value.

    So, the decimal fraction given by the numeral in the source
    code is possibly being distorted twice when it is represented
    by a double and then converted to a string, but only once when
    it is represented as a double.
    Stefan Ram, Jul 17, 2008
    #2
    1. Advertising

  3. Stanimir Stamenkov wrote:
    > I've observed depending on whether a BigDecimal is constructed with a
    > String or double representing the same value, I get different results in
    > a rounding operation:
    >
    > import java.math.BigDecimal;
    > import java.math.RoundingMode;
    > public class FPTest {
    > public static void main(String[] args) {
    > double a = 3.1231215;
    > BigDecimal b = new BigDecimal(a);
    > BigDecimal c = new BigDecimal(Double.toString(a));
    > System.out.println(b.setScale(6, RoundingMode.HALF_UP));
    > System.out.println(c.setScale(6, RoundingMode.HALF_UP));
    > }
    > }
    >
    > The output I get is:
    >
    > 3.123121
    > 3.123122
    >
    > How are the two constructors BigDecimal(String) and BigDecimal(double)
    > different?
    >


    The issue is that 3.1231215 is not exactly representable as a double.

    Double.toString(x) does not return the exact String representation of
    x's value. It returns the shortest String that would round to x's value
    on conversion to double. As a result, c could be exactly 3.1231215.

    On the other hand, b is forced to have a value that is exactly
    representable as a double, and therefore cannot be exactly 3.1231215.
    From the results, it appears to be slightly less. You could check all
    this by printing the values of b and c without prior rounding.

    new BigDecimal("3.1231215") would be certain to produce a BigDecimal
    with exactly the specified value. Generally, if you want the exact
    decimal handling of BigDecimal, it is a mistake to ever let a value be
    converted to double.

    Patricia
    Patricia Shanahan, Jul 17, 2008
    #3
  4. Stanimir Stamenkov

    Arne Vajhøj Guest

    Stanimir Stamenkov wrote:
    > I've observed depending on whether a BigDecimal is constructed with a
    > String or double representing the same value, I get different results in
    > a rounding operation:
    >
    > import java.math.BigDecimal;
    > import java.math.RoundingMode;
    > public class FPTest {
    > public static void main(String[] args) {
    > double a = 3.1231215;
    > BigDecimal b = new BigDecimal(a);
    > BigDecimal c = new BigDecimal(Double.toString(a));
    > System.out.println(b.setScale(6, RoundingMode.HALF_UP));
    > System.out.println(c.setScale(6, RoundingMode.HALF_UP));
    > }
    > }
    >
    > The output I get is:
    >
    > 3.123121
    > 3.123122
    >
    > How are the two constructors BigDecimal(String) and BigDecimal(double)
    > different?


    Read:

    http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)

    Arne
    Arne Vajhøj, Jul 18, 2008
    #4
  5. Thu, 17 Jul 2008 19:34:58 -0400, /Arne Vajhøj/:
    > Stanimir Stamenkov wrote:
    >
    >> How are the two constructors BigDecimal(String) and BigDecimal(double)
    >> different?

    >
    > Read:
    >
    > http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)


    Thank you, Arne, Patricia and Stefan for your replies. I now feel
    much confident in what's going on. May be the detail I've been
    missing mainly is the Double.toString(double) conversion.

    --
    Stanimir
    Stanimir Stamenkov, Jul 18, 2008
    #5
    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. Sydex
    Replies:
    12
    Views:
    6,454
    Victor Bazarov
    Feb 17, 2005
  2. Replies:
    3
    Views:
    1,213
  3. Saraswati lakki
    Replies:
    0
    Views:
    1,298
    Saraswati lakki
    Jan 6, 2012
  4. David Garamond
    Replies:
    20
    Views:
    336
  5. teeshift
    Replies:
    2
    Views:
    242
    Chris Pearl
    Dec 1, 2006
Loading...

Share This Page