Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!

# Precision loss

Shamsudeen Akanbi
Ranch Hand
Posts: 85
1
Hi Ranchers, I'm trying to find the result of 2^1000. With "double x = Math.pow(2,1000)". The result is deviating, i mean its rounding it off at a particular limit and I need the full values. Can someone please help?

fred rosenberger
lowercase baba
Bartender
Posts: 12124
30
A double does not guarantee precision. There are limits to what you can do with only so many bits...

Further, why would you use something designed to store floating point decimal numbers when you are computing what is clearly an integer value?

If you need something more accurate, look at something like the BitInteger class.

Winston Gutkowski
Bartender
Posts: 10417
63
fred rosenberger wrote:If you need something more accurate, look at something like the BitInteger class.

I think that's BigInteger, Fred.

@Shamsudeen - More specifically, something like:
private static final BigInteger TWO = BigInteger.valueOf(2L); (I don't know why BigInteger doesn't define this constant itself)
and then elsewhere in your code:
TWO.pow(1000);

Winston

Campbell Ritchie
Sheriff
Posts: 48954
60
Shamsudeen Akanbi wrote: . . . With "double x = Math.pow(2,1000)". The result is deviating, i mean its rounding it off at a particular limit . . .
All the primitives have limits of range, and the floating-point types have limits to their precision, too. The limits are clearly stated in the Java Language Specification and Java Tutorials, and you can find more by Googling for IEEE754. 2 to the 1000 is actually inside the range of a double, so you won’t get infinitiy, but it will tell you it is only precise to 15 or 16 Significant figures. Floating-point arithmetic is designed for engineers to use.

What’t an engineer?

He’s somebody you ask “What’s 2×2?”, and he gets his slide‑rule and says, “ . . . two by two . . . three point nine nine . . . that’s four, near as makes no difference.”
Floating-point arithmetic is intended for people who don’t mind such imprecision. You have already been given the correct solution, twice, with and without spelling errors

Winston Gutkowski
Bartender
Posts: 10417
63
Campbell Ritchie wrote:When I was an undergraduate: What's an engineer?...

Nice one.

Winston

Winston Gutkowski
Bartender
Posts: 10417
63
Winston Gutkowski wrote:TWO.pow(1000);Winston

BTW: If you fancy it (and you have the memory space and - possibly more importantly - time )
try:
BigInteger FOUR = new BigInteger.valueOf(4L);
System.out.println(FOUR.pow(1073741824).bitLength());

I've never got it to work; probably because my heap memory is too small (possibilities run to anywhere around 3Gb, depending on efficiency) and I can't be bothered to fix it; but I suspect very strongly that it will display a negative number..SILENTLY. And this after repeated queries about it to Oracle and Sun.

Winston

Campbell Ritchie
Sheriff
Posts: 48954
60
You already know its bit length. I can tell you it free. 2147483649.

Winston Gutkowski
Bartender
Posts: 10417
63
Campbell Ritchie wrote:You already know its bit length. I can tell you it free. 2147483649.

And BigInteger.bitLength() returns what?

Winston

Campbell Ritchie
Sheriff
Posts: 48954
60
2147483649. Presumably rounded with the ROUND_PEG_SQUARE_HOLE algorithm, to the nearest int.

. . . And how long does it take to run? (Or crash?)

Winston Gutkowski
Bartender
Posts: 10417
63
Campbell Ritchie wrote:2147483649. Presumably rounded with the ROUND_PEG_SQUARE_HOLE algorithm, to the nearest int.
. . . And how long does it take to run? (Or crash?)

Actually, nanoseconds; unless the number is negative and an exact power of 2; so, on average...

My objection is theoretical: bitLength() returns an int, which has a limit of 23^31 -1. The magnitude of a BigInteger is held in an int[], which can hold up to ≈2^36 bits. I've just never been able to prove that it does what I think it will.

Winston

Campbell Ritchie
Sheriff
Posts: 48954
60
Winston Gutkowski wrote: . . . unless the number is negative and an exact power of 2; so, on average... . . .
How can a number be negative and an exact power of 2?

I did work out that something would go wrong, so I said it would use the ROUND_PEG_SQUARE_HOLE algorithm. I have had the d*mn thing running for several hours with no sign of any output yet.

Winston Gutkowski
Bartender
Posts: 10417
63
Campbell Ritchie wrote:
Winston Gutkowski wrote: . . . unless the number is negative and an exact power of 2; so, on average... . . .
How can a number be negative and an exact power of 2?

I guess I should have said -(2^n).

BigIntegers hold their values in sign/magnitude form, and bitLength() is defined as returning:
"the number of bits in the minimal two's-complement representation of this BigInteger, excluding [the] sign bit."

I take that to mean "the number of bits from the first one in the 2's-C form that differs from the sign bit"; otherwise the check doesn't make much sense.
Personally, I think they could've saved themselves a lot of bother by simply returning the bit length of the absolute value, but maybe they had their reasons.

BTW: How did your attempt work out?

Winston

Campbell Ritchie
Sheriff
Posts: 48954
60
I gave up after it had a day, on and off, and still hadn’t completed. I had to close the shell to terminate it; even ctrl-C didn’t seem to stop it