Problems with double
I'm storing a number as a double
. It works well with small numbers but if the double
is 1000000 and I try to add 10 to it, it doesn't work but I can add 100 to it. If the double
is 100000 and I try to add 1 to it, it doesn't work but I can add 10 to it.
Is this a problem with using a double
? What format should I be using for up to a 9 digit number?
Edit: I'm doing calculations on the number and putting it in a 0.00 decimal format. It works on sma开发者_开发问答ll numbers but not on big. It might have something to do with the other calculations. Just seeing if maybe double was the problem.
I run into problems when I take 1000001 / 100 and put in 0.00 decimal format. But 1000100 / 100 put into a 0.00 dec format works.
Not sure what you mean by "it doesn't work", considering that it should:
System.out.println(1000000d + 10d); // 1000010.0
Cases where it wouldn't work are where there is a value that is more than about 15 digits from the most significant digit of the largest double involved:
System.out.println(Math.pow(10, 18) + 10d - Math.pow(10, 18)); // 0.0
System.out.println(Math.pow(10, 17) + 10d - Math.pow(10, 17)); // 16.0
System.out.println(Math.pow(10, 16) + 10d - Math.pow(10, 16)); // 10.0
An int
is absolutely large enough to store a 9-digit number, since the maximum value stored by a (signed) integer is 2^31 - 1 = 2,147,483,647
which has 10 digits.
If you need a larger range, use a long
.
Java Tutorial: Primitive Data Types
Yes, this is how floating point works in general. (Although, as others pointed out, this should be well within the actual capabilities of double
.) It loses more and more precision as the number is getting bigger. And even with small numbers, it isn't guaranteed to be precise. For small integers it is, as a general rule, but in practice, relying on the precision of floating point is a bad idea.
For integers, long
should be good enough, 263-1 is the biggest number you can store in it.
Otherwise BigDecimal
is the answer. Not very convenient, but it is precise.
Judging by the update to your question, you want to store prices or something similar. In that case, you can either use a library dedicated to currency arithmetic (as there are often weird rules of rounding involved for example), or store pennies/cents in a long
.
A double is actually able to hold that result. The most likely thing is probably that you're inspecting/printing out the number in such a way that appears like the number isn't different (could you post your test code?).
As a general rule of thumb, doubles give you ~16 digits of precision, and floats give you ~8 digits of precision.
What kind of 9-digit number do you need to keep? A double
should have enough precision track 9 significant digits as would an int
, but you need to know which type of number you need before you choose a type. If you need real values (i.e., they have digits to the right of the decimal), then choose double. If they are integers, choose int
.
I don't think your exact problem is very clear. Are you using integer arithmetic? In which case you should expect an integer division to round down the answer.
int i = 1000001 / 100;
System.out.println(i);
double d = (double) 1000001 / 100;
System.out.println(d);
prints as expected
10000
10000.01
However, since you have't given a clear example of what does work and what you expect to happen, we are just guessing what your problem might be.
Nevertheless, there is something wrong. It should be possible to (ab)use a double (which is in 64bit IEEE format in Java) as an 48-bit-or so integer. 48 bt should be enough to store 9 decimal digits.
精彩评论