• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Precision loss

 
Shamsudeen Akanbi
Ranch Hand
Posts: 85
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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: 12188
34
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 49864
71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.

When I was an undergraduate:
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
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:When I was an undergraduate: What's an engineer?...

Nice one.

Winston
 
Winston Gutkowski
Bartender
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 49864
71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You already know its bit length. I can tell you it free. 2147483649.
 
Winston Gutkowski
Bartender
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 49864
71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 49864
71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 10509
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Pie
Posts: 49864
71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic