Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

BigDecimal interesting problem

 
Darryl Nortje
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howzit guys.

The question has been asked before with BigDecimal.toString returning scientific notation. The solution is to use toPlainString();

We have just moved our test environment from a Solaris box to a Linux box. And suddenly we started getting problems. I tracked the problem down to this line.

<blockquote>code:
<pre name="code" class="core">trustee.trusteeId = Long.parseLong(result.getTrusteeId().toString());</pre>
</blockquote>

Where the attribute trusteeId is a long and result.getTrusteeId() is a BigDecimal. The result object is a CocoBase object, and populated by a CocoBase select.

So, this line worked on the Solaris box, and now does not work on the Linux box. The jre version on both machines is 1.5.0_07-b03 so this is not a jre version issue. Then in the API documentation for toString in BigDecimal it says this "The string produced for a given number is always the same; it is not affected by locale".

Then to confuse me even further, on my dev box, which is also Linux, and using the same version JRE, this works.

So I put some logs in, and this is what gets returned on the 3 different machines.

<blockquote>code:
<pre name="code" class="core">System.out.println(result.getTrusteeId().toString()</pre>
</blockquote>
Solaris box and my dev machine --> 1
New Test Linux box --> 0E+127

So my question. Why does this print 0E+127. Where could that possibly come from? I just need to understand why this is happening. Can anyone help please? ;-)

cheers
Darryl
 
Piet Verdriet
Ranch Hand
Posts: 266
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is (almost) never a good idea to be dependent on what toString() returns.
IMHO, a better solution would be to make use of BigDecimal's longValue() method.

http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html#longValue()
 
Darryl Nortje
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Piet, and everyone.

I agree with you Piet, and long before this post I has already changed it to that. That wasn't my question however. I'm trying to understand how on earth on these 3 different machines, it worked on 2 of them, and the other one not.

They are all 3 32 bit operating systems and cpu's (that's the level that i'm getting into now...) so still no joy. Can anyone explain why BigDecimal.toString will return 0E+127 (for the number '1' by the way) and then on 2 other machines, the actual number. In principle it doesn't make any sense. But there must be a reason why.
 
Carey Evans
Ranch Hand
Posts: 225
Debian Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The IEEE single-precision floating point representation for the number one has 0 in the fraction bits and 127 in the exponent bits. Do you have �float� values coming into your application anywhere?

Example: <blockquote>code:
<pre name="code" class="core">int bits = Float.floatToRawIntBits(1.0f);
System.out.println(bits & (1 << 23 - 1));
System.out.println(bits >> 23);
</pre>
</blockquote>
 
Darryl Nortje
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howzit Carey,

I was also going down that alley, and assumed that i did. So there is obviously something wrong with the CocoBase ORM and how it's matching a normal database NUMBER type to the class. The generated class has a BigDecimal as the match.

That said, it still doesn't explain why BigDecimal.toString returns 0E+127 in the 1 environment, and "1" in the other 2 enviroments. That's actually the part that i was hoping to get an answer on.
 
Darryl Nortje
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have found out why this was happening. Very very interesting indeed.

This is apparently an oracle bug, with java 1.5. See this website. The problem here is even more scary than mine but highlights the bug quite nicely.

Basically, what was going wrong with mine was that I had 2 oracle drivers in my classpath, and in the 2 environments the classloader was loading 1.2 first, but in the new test environment the classloader got hold of 1.4 first.

And the 1.4 driver has a problem with new jdk1.5 changes to the way BigDecimal stores numbers, in that it case have negative exponant values.

That's that.

Thanks all for the replies, have a lekker weekend.

Tjeers
Darryl
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic