bigDecimal qs

Discussion in 'Java' started by sami.jan@gmail.com, Sep 11, 2006.

  1. Guest

    Hi

    I am new to Java. I have to use BigDecimal to do some data conversions
    (app limitation) and have run into something I cannot understand.
    ------
    BigDecimal bd, bd2;

    bd2 = new BigDecimal(12345678901); //This throws an error - Out of
    Range

    bd = new BigDecimal("12345678901");
    bd2 = new BigDecimal("12345678901");
    System.out.println(bd.add(bd2));


    Output for the last line is: 24691357802 (i.e. addition was successful)

    ------
    How can this work? If 12345678901 is out of range, how can
    "12345678901" be in range? and math operations for these bigdecimals
    work too

    Thanks

    Sami
    , Sep 11, 2006
    #1
    1. Advertising

  2. Daniel Dyer Guest

    On Mon, 11 Sep 2006 13:18:35 +0100, <> wrote:

    > Hi
    >
    > I am new to Java. I have to use BigDecimal to do some data conversions
    > (app limitation) and have run into something I cannot understand.
    > ------
    > BigDecimal bd, bd2;
    >
    > bd2 = new BigDecimal(12345678901); //This throws an error - Out of
    > Range
    >
    > bd = new BigDecimal("12345678901");
    > bd2 = new BigDecimal("12345678901");
    > System.out.println(bd.add(bd2));
    >
    > Output for the last line is: 24691357802 (i.e. addition was successful)
    >
    > ------
    > How can this work? If 12345678901 is out of range, how can
    > "12345678901" be in range? and math operations for these bigdecimals
    > work too


    It's the integer literal that you pass to the constructor that is out of
    range, not the BigDecimal itself. The biggest permitted value is 2^31.
    You should use a long instead, which has a maximum value of 2^63. To do
    this, append an 'L' to the literal:

    bd2 = new BigDecimal(12345678901L);

    You can use uppercase L or lowecase but uppercase is best because
    lowercase looks like a one.

    Dan.

    --
    Daniel Dyer
    http://www.dandyer.co.uk
    Daniel Dyer, Sep 11, 2006
    #2
    1. Advertising

  3. Daniel Dyer wrote:
    > On Mon, 11 Sep 2006 13:18:35 +0100, <> wrote:
    >
    >> Hi
    >>
    >> I am new to Java. I have to use BigDecimal to do some data conversions
    >> (app limitation) and have run into something I cannot understand.
    >> ------
    >> BigDecimal bd, bd2;
    >>
    >> bd2 = new BigDecimal(12345678901); //This throws an error - Out of
    >> Range
    >>
    >> bd = new BigDecimal("12345678901");
    >> bd2 = new BigDecimal("12345678901");
    >> System.out.println(bd.add(bd2));
    >>
    >> Output for the last line is: 24691357802 (i.e. addition was successful)
    >>
    >> ------
    >> How can this work? If 12345678901 is out of range, how can
    >> "12345678901" be in range? and math operations for these bigdecimals
    >> work too

    >
    > It's the integer literal that you pass to the constructor that is out of
    > range, not the BigDecimal itself. The biggest permitted value is 2^31.
    > You should use a long instead, which has a maximum value of 2^63. To do
    > this, append an 'L' to the literal:
    >
    > bd2 = new BigDecimal(12345678901L);
    >
    > You can use uppercase L or lowecase but uppercase is best because
    > lowercase looks like a one.


    Also, in case you need to go beyond the long range, consider:

    new BigDecimal("12345678901");

    For smaller values, that can be represented using long, or long and a
    scale, consider using the static valueOf methods. They can return
    predefined literals and cached objects to reduce the number of distinct
    BigDecimal objects. The constructors must always return a new object.

    Patricia
    Patricia Shanahan, Sep 11, 2006
    #3
  4. Guest

    thanx Patricia and Daniel

    Sami

    Patricia Shanahan wrote:
    > Daniel Dyer wrote:
    > > On Mon, 11 Sep 2006 13:18:35 +0100, <> wrote:
    > >
    > >> Hi
    > >>
    > >> I am new to Java. I have to use BigDecimal to do some data conversions
    > >> (app limitation) and have run into something I cannot understand.
    > >> ------
    > >> BigDecimal bd, bd2;
    > >>
    > >> bd2 = new BigDecimal(12345678901); //This throws an error - Out of
    > >> Range
    > >>
    > >> bd = new BigDecimal("12345678901");
    > >> bd2 = new BigDecimal("12345678901");
    > >> System.out.println(bd.add(bd2));
    > >>
    > >> Output for the last line is: 24691357802 (i.e. addition was successful)
    > >>
    > >> ------
    > >> How can this work? If 12345678901 is out of range, how can
    > >> "12345678901" be in range? and math operations for these bigdecimals
    > >> work too

    > >
    > > It's the integer literal that you pass to the constructor that is out of
    > > range, not the BigDecimal itself. The biggest permitted value is 2^31.
    > > You should use a long instead, which has a maximum value of 2^63. To do
    > > this, append an 'L' to the literal:
    > >
    > > bd2 = new BigDecimal(12345678901L);
    > >
    > > You can use uppercase L or lowecase but uppercase is best because
    > > lowercase looks like a one.

    >
    > Also, in case you need to go beyond the long range, consider:
    >
    > new BigDecimal("12345678901");
    >
    > For smaller values, that can be represented using long, or long and a
    > scale, consider using the static valueOf methods. They can return
    > predefined literals and cached objects to reduce the number of distinct
    > BigDecimal objects. The constructors must always return a new object.
    >
    > Patricia
    , Sep 11, 2006
    #4
  5. EJP Guest

    wrote:

    > bd2 = new BigDecimal(12345678901); //This throws an error - Out of
    > Range


    No it doesn't. It generates a compile error for the integer value that
    is too large.
    EJP, Sep 12, 2006
    #5
  6. steen Guest

    EJP wrote:
    > wrote:
    >
    > > bd2 = new BigDecimal(12345678901); //This throws an error - Out of
    > > Range

    >
    > No it doesn't. It generates a compile error for the integer value that
    > is too large.


    Also you should consider making it a habit to always use the
    BigDecimal(String) constructor. That way you wont run into the problem
    with the BigDecimal(Double) constructor. Try just for the fun of it :
    System.out.println(new java.math.BigDecimal(0.1));
    and try to guess the output before running it..;)

    /Steen
    steen, Sep 12, 2006
    #6
  7. EJP Guest

    steen wrote:
    > Also you should consider making it a habit to always use the
    > BigDecimal(String) constructor. That way you wont run into the problem
    > with the BigDecimal(Double) constructor. Try just for the fun of it :
    > System.out.println(new java.math.BigDecimal(0.1));
    > and try to guess the output before running it..;)


    The 'problem' with the BigDecimal(double) constructor is generally
    overstated. I should know because I've overstated it myself.

    The *real* problem with the above is with the conversion of 0.1 to a
    double at compile time. Nothing to do with BigDecimal. Try *this*:

    System.out.println(new java.math.BigDecimal(Math.pow(2.0,-32.0));
    System.out.println(new java.math.BigDecimal(""+Math.pow(2.0,-32.0));

    The first line prints the more accurate result. The second line is
    entirely and invisibly dependent on rounding that takes place inside
    String.valueOf(double) which is not well-specified and which in turn
    actually calls Double.toString(double);
    EJP, Sep 13, 2006
    #7
  8. Chris Uppal Guest

    EJP wrote:

    > [...]
    > entirely and invisibly dependent on rounding that takes place inside
    > String.valueOf(double) which is not well-specified and which in turn
    > actually calls Double.toString(double);


    That isn't really true. String.valueOf(double) is documented to be identical
    to Double.toString(double), and that latter method is specified quite
    carefully. From the JavaDoc:

    ========
    There must be at least one digit to represent the fractional part, and beyond
    that as many, but only as many, more digits as are needed to uniquely
    distinguish the argument value from adjacent values of type double. That is,
    suppose that x is the exact mathematical value represented by the decimal
    representation produced by this method for a finite nonzero argument d. Then d
    must be the double value nearest to x; or if two double values are equally
    close to x, then d must be one of them and the least significant bit of the
    significand of d must be 0.

    ========

    which I believe specifies the "rounding" completely.

    "Precisely specified" and "does what you want it to do" are, of course, not
    necessarily the same...

    -- chris
    Chris Uppal, Sep 13, 2006
    #8
  9. EJP wrote:
    > The 'problem' with the BigDecimal(double) constructor is generally
    > overstated. I should know because I've overstated it myself.
    >
    > The *real* problem with the above is with the conversion of 0.1 to a
    > double at compile time. Nothing to do with BigDecimal. Try *this*:
    >
    > System.out.println(new java.math.BigDecimal(Math.pow(2.0,-32.0));
    > System.out.println(new java.math.BigDecimal(""+Math.pow(2.0,-32.0));
    >
    > The first line prints the more accurate result. The second line is
    > entirely and invisibly dependent on rounding that takes place inside
    > String.valueOf(double) which is not well-specified and which in turn
    > actually calls Double.toString(double);


    That example is rather useless.

    The problem is with floating point representation.

    BigDecimal(double) does not necessarily match the source code.

    BigDecimal(String) do match the source code).

    BigDecimal(string expression based on a floating point calculation)
    ofcourse has the same floating point problems as the first, but it
    is a problem in the expression calculation not in the constructor.

    Arne
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Sep 13, 2006
    #9
    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. Forrest Hump
    Replies:
    4
    Views:
    24,235
    Mark Meyer
    Aug 22, 2003
  2. Cory Musselman

    Problems with XMLEncoder and BigDecimal

    Cory Musselman, Oct 30, 2003, in forum: Java
    Replies:
    0
    Views:
    2,221
    Cory Musselman
    Oct 30, 2003
  3. wald

    BigDecimal: Sun? IBM?

    wald, Dec 3, 2004, in forum: Java
    Replies:
    4
    Views:
    1,851
    jddarcy
    Dec 10, 2004
  4. Replies:
    3
    Views:
    1,211
  5. Stanimir Stamenkov
    Replies:
    4
    Views:
    2,562
    Stanimir Stamenkov
    Jul 18, 2008
Loading...

Share This Page