Isn't double able to represent any 2^n number without precision issues? n is natural

238 views Asked by At

This code:

double x = 2.0;
for(int i = 1 ; i<1024 ; i+=i) {
    Console.WriteLine( String.Format( "2^{0} = {1:F0}", i, x ) );
    x*=x;
}

Outputs:

2^1 = 2
2^2 = 4
2^4 = 16
2^8 = 256
2^16 = 65536
2^32 = 4294967296
2^64 = 18446744073709600000
2^128 = 340282366920938000000000000000000000000
2^256 = 115792089237316000000000000000000000000000000000000000000000000000000000000000
2^512 = 13407807929942600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

I thought that double's formula is sign * 2 ^ exponent * fraction; To Illustrate my situation; With setting the fraction to 0.5, the sign to positive, and by setting exponent to any value between -1024 to 1023, I can present any 2^n number that is in the exponent's range; What is wrong with this deduction? Is the formula incomplete?

4

There are 4 answers

10
Michael Liu On BEST ANSWER

A double can represent powers of 2 exactly, as demonstrated by the following code (which uses Jon Skeet's DoubleConverter class):

Console.WriteLine(String.Format("2^{0} = {1}", i, DoubleConverter.ToExactString(x)));

For the F0 specifier, why did the .NET designers choose to round the value off after the 15 most significant decimal digits?

My guess: Displaying the exact value (such as 18446744073709551616) might imply that the double is precise to all those digits, when in fact a double cannot distinguish between that value and 18446744073709600000. Also, displaying a rounded value is consistent with exponential notation: 1.84467440737096E+19.

7
Ben Voigt On

No. Your argument fails at "by setting exponent to any value".

There's a limited range on exponent, you cannot represent

pow(2, 1000000)

even though 1000000 is a natural number.

0
John On

http://msdn.microsoft.com/en-us/library/678hzkk9.aspx

The double keyword signifies a simple type that stores 64-bit floating-point values. The following table shows the precision and approximate range for the double type.

Type
double

Approximate range
±5.0 × 10−324 to ±1.7 × 10308

Precision
15-16 digits
0
Nicholas Carey On

That answer to your question is that an IEEE 754 double precision number is a 64-bit value:

  • 1 bit is the sign
  • 11 bits represent the exponent
  • 52 bits represent the significand (but due to a little deep magick, the signficand actually has 53 bits of precision).

It can represent no more than 264 discrete values — the same as a 64-bit integer (and actually less due to things like NaN, positive and negative zero, etc.)

Its range, however, is much larger than that of a 64-bit integer: it can represent decimal values roughly from 10-308 to 10+308 ... albeit with with no more than 15 to 17 decimal digits of precision.

Floating point trades precision for range. It's a tradeoff.

See IEEE-754 Double Precision Binary Floating Point Format for rather more details.

Even better, read David Goldberg's 1991 paper, "What every computer scientist should know about floating-point arithmetic":

Abstract. Floating-point arithmetic is considered as esoteric subject by many people. This is rather surprising, because floating-point is ubiquitous in computer systems: Almost every language has a floating-point datatype; computers from PCs to supercomputers have floating-point accelerators; most compilers will be called upon to compile floating-point algorithms from time to time; and virtually every operating system must respond to floating-point exceptions such as overflow. This paper presents a tutorial on the aspects of floating-point that have a direct impact on designers of computer systems. It begins with background on floating-point representation and rounding error, continues with a discussion of the IEEE floating point standard, and concludes with examples of how computer system builders can better support floating point.

David Goldberg. 1991. "What every computer scientist should know about floating-point arithmetic". ACM Comput. Surv. 23, 1 (March 1991), 5-48. DOI=10.1145/103162.103163 http://doi.acm.org/10.1145/103162.103163