• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

Converting BigDecimal to double

 
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I am getting random run time exception when converting BigDecimal to double. The exception is the NumberFormatException. Since we are doing lots of scientific calucaltion, our precision is up to 14 position after the decimal point.

The exception is as the followings:

java.lang.NumberFormatException: For input string: "0.0000000000null"

I am sure the input string isn't "0.0000000000null" when I use it to create the BigDecimal object. It seems the object changes itself after hours application run.

Has anybody encountered similar problem? Again, the exception is random and not repeatable. It could happen anywhere.

Thanks
Elinor
 
Sheriff
Posts: 3064
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's very odd. The source code I'm looking at would make that error impossible. There could be a case if you used the BigDecimal(BigInteger, int scale) constructor, where the constructor wouldn't complain, but doubleValue() would fail with a NullPointerException. It's actually calling toString() and then parsing that String into a double.

What exact version of the JDK are you using? Also, BigDecimal is not a final class. Are you sure you aren't working with a subclass?
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with Greg's comments, plus:

[Elinor]: I am sure the input string isn't "0.0000000000null" when I use it to create the BigDecimal object. It seems the object changes itself after hours application run.

That seems unlikely as BigDecimal is supposed to be immutable. (You're not using reflection somewhere to change values, are you?) Are you using the doubleValue() conversion method, or something else? (If something else, please show us.)

If you could insert some logging immediately after this instance is created, and also immediately before the attempted conversion, that could be useful. Something like:

Does the string value really say null just before conversion? And if so, can you find an earlier entry where that same instance was created? What was the string value then?
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Elinor Chang:
[QB]I am getting random run time exception when converting BigDecimal to double. The exception is the NumberFormatException. Since we are doing lots of scientific calucaltion, our precision is up to 14 position after the decimal point.


Are you converting a BigDecimal to double, or is it the other way around - converting a double to a BigDecimal?

Show us the stack trace and a few lines of source code where the exception happens (the stack trace tells you in which line in which source file the exception happens). That will make it much easier to help you - without the exact error message and some source code we can only guess what's happening in your application.
 
Elinor Chang
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is the stack trace I have so far.

java.lang.NumberFormatException: For input string: "0.0000000000null"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1207)
at java.lang.Double.valueOf(Double.java:202)
at java.math.BigDecimal.doubleValue(BigDecimal.java:1033)

It happends when converting BigDecimal to a double not the other way around.

On the other hand, I don't set the BigDecimal which is obtained from Database table. The corresponding column was decleared as decimal(16, 14). I start to suspecting on the data retrival part. I am using Hibernate to get data...

Any idea?
Thanks for all your response so far.
 
Elinor Chang
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The JDK I am using is 1.4.2. App Server WebLogic 8.1 Sp3...
 
Elinor Chang
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Three more line of error log. I don't use reflection when converting a BigDecimal to double using .doubleValue() but it seems the application does that itself. Any problem on that?

at sun.reflect.GeneratedMethodAccessor305.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Elinor]: I don't use reflection when converting a BigDecimal to double using .doubleValue() but it seems the application does that itself. Any problem on that?

No, that's fine. When I mentioned reflection I was talking about using it to directly access fields within the BigDecimal class, bypassing the public methods of the class. You call stack shows it's still giong in through doubleValue(), and anyway it's not changing the value there. There's no problem with the reflection used here.

[Elinor]: I start to suspecting on the data retrival part.

I agree. Most likely this BigDecimal was broken at creation time.

[Elinor]: I am using Hibernate to get data... Any idea?

I would try to confirm this by checking the value of the BigDecimal as soon as possible after it's been loaded. (See my previous comment about logging statements.) If you can confirm the problem is in this area, I'd ask this question in the Object Relational Mapping forum, which covers Hibernate.
 
Elinor Chang
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks. I just posted a topic in the forum. Hopefully someone can shine some light on it. On the other hand, I doubt it's hiberate that causes it. Hibernate calls JDBC behind the scene. It might go all the way back to be a glitch on BigDecimal constructor that uses a String.

What do you think about the way of constructing a BigDecimal as the following:

double d = 0.1;
double b = -0.1
double e = d + b;
BigDecimal f = new BigDecimal(""+e);

My further invesitgation narrows the scope down to this line. Since the application does heavy duty scientific calculation, is it possible the ""+e becomes "0.00000000000null"? considering double doesn't keep the precision.

Thanks
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Elinor]: What do you think about the way of constructing a BigDecimal as the following:

Seems a little silly - why not just use the new BigDecimal(double) constructor? But it should work.

Since the application does heavy duty scientific calculation, is it possible the ""+e becomes "0.00000000000null"? considering double doesn't keep the precision.

I don't think so, and that doesn't happen when I run that code. Have you tried it on your machine?
 
Greg Charles
Sheriff
Posts: 3064
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I still can't figure out how it's possible. BigDecimal stores its value internally as a BigInteger and an integer scale. When you call doubleValue(), it first gets a String representation of the BigDecimal, then uses java.lang.Double to parse it. (Even if you used a String to contruct the BigDecimal, that's not what it's using.) If the BigInteger part was null, which is possible through various constructors, then you would fail with a NullPointerException. However, what you are seeing is the toString() method of BigInteger returning null. From what I can see of the BigInteger source, that's simply impossible, no matter how gooped up the internal values are.

I suggest that somehow BigDecimal has been subclassed, or that BigInteger has been subclassed and been used to construct the BigDecimal. You can check the concrete class of your BigDecimal directly. For the internal BigInteger ... well you might be able to look at the class if you can catch it in a debugger. If that's what happening, then I guess it's Hibernate that's doing it. It may be a reported bug somewhere.
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Greg]: I still can't figure out how it's possible.

Me neither so far. But there are a lot of internals to sort through here...

However, what you are seeing is the toString() method of BigInteger returning null.

Looks to me like toString() is returning "0.00000000000null". I'm not sure which part internally the null is coming from. Was thinking it might come from BigInteger's toString(int) method screwing up the count of numGroups? Hard to say.

Elinor, it would really be useful to know just what value this BigDecimal had before doubleValue() was invoked. See if you can log the values of f.scale(), f.precision(), and f.unscaledValue() for example. And f.getClass(), and f.unscaledValue().getClass(). Because Greg's suggestion that one of those might be a subclass is more plausible than anything else we've seen so far.
 
Sheriff
Posts: 28371
99
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If this error is happening very rarely, then it's possible that unusual numbers are causing it. But I tried with NaN and the "infinities" and got different error messages than that one, so that doesn't look very likely.

However, since you're running this in a Web app container, is it possible that there are violations of thread safety occurring? It might be hard to tell, especially if it's the constructor of BigDecimal that is using some object that isn't thread-safe.
 
Elinor Chang
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks everybody's input. Back to some questions you asked.

1. new BigDecimal(""+adouble) vs. new BigDecimal(adouble)

It's not silly to use the first constuctore because it ensure the BigDecimal has the exact number adouble represents. It's actually the best way to create a BigDecimal.

2. Using thread safe object.

We are using HashMap in session bean. Since EJB can garantee thread safe and we don't have the case when two thread modify the HashMap instance at the same time, I don't think the multi-threading is the culprit.

I will try to catch the run time exception and do something....

On the other hand, if anybody has experience in ILOG JRule Engine please let me know if the ILOG exeuction model does something funny when dealing with BigDecimal...

Thanks!
 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
<two-cents>
I don't know if anyone has mentioned it yet, but my best guess is that you have a race condition that is consistently occurring. It only takes a few seconds to figure out what is happening under a debugger though quite often, a race condition exhibits different behaviour under a debugger. In all cases, it's a 30 second diagnosis.
</two-cents>
 
Hey, I'm supposed to be the guide! Wait up! No fair! You have the tiny ad!
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic