简体   繁体   中英

Java convert/cast object to Double but prevent round?

Object num = 12334555578912349.13;

System.out.println(BigDecimal.valueOf(((Number) num).doubleValue()).setScale(2, BigDecimal.ROUND_HALF_EVEN));

I expect the value to be 12334555578912349.13 but output is 123345555789123504.00

How can I prevent it from rounding?

 Object num = 12334555578912349.13;

You already lost here. As per the java spec, the literal text '12334555578912349.13' in your source file is interpreted as a double. A double value, given that computers aren't magic, is a 64-bit value, and thus, only at most 2^64 numbers are even representable by it. Let's call these the 'blessed numbers'. 12334555578912349.13 is not one of the blessed numbers. The nearest blessed number to that is 123345555789123504.0 which is what that value 'compiles' to. Once you're at 123345555789123504.0, there's no way back.

The solution then is to never have '12334555578912349.13' as literal in your source file, as that immediately loses you the game if you do that.

Here's how we avoid ever having a double anywhere:

var bd = new BigDecimal("12334555578912349.13");
System.out.println(bd);

In general if you want to provide meaningful guarantees about precision, if your code contains the word double anywhere in it, you broke it. Do a quick search through the code for the word 'double' and until that search returns 0 hits, keep eliminating its use.

Alternatives that can provide guarantees about precision:

  • BigDecimal, of course. Note that BD can't divide without specifying rules about how to round it (for the same reason 1/3 becomes 0.333333... never ends).
  • Eliminate the fraction. For example, if that represents the GDP of a nation, store it as cents and not as euros, in a long and not a double .
  • If the thing doesn't represent a number that you ever intend to do any math on (for example, it's a social security number or an ISBN code or some such), store it as a String.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM