7

In the lunch break we started debating about the precision of the double value type.

My colleague thinks, it always has 15 places after the decimal point.

In my opinion one can't tell, because IEEE 754 does not make assumptions about this and it depends on where the first 1 is in the binary representation. (i.e. the size of the number before the decimal point counts, too)

How can one make a more qualified statement?

Mare Infinitus
  • 8,024
  • 8
  • 64
  • 113
  • Are you reasoning in absolute terms or according to scientific notation? How would you consider a number such as 0.001e5 ? – Nicola Musatti Aug 23 '12 at 11:21
  • We were talking exactly about that. My collegue insists on having 15 places after the decimal point. My opinion is that you have a 53 bit mantissa for all places. But there seem to be difficulties to explain that in a qualified way. – Mare Infinitus Aug 23 '12 at 11:26
  • Just to make it more clear: This is especially a C# issue. If the internal C# representation is not IEEE 754 but 15 places after the decimal point, this is extremly interesting. – Mare Infinitus Aug 23 '12 at 11:41
  • The internal representation of C# doubles is indeed IEEE 754, or rather IEC 60559 which is the corresponding international standard. – Nicola Musatti Aug 23 '12 at 12:04

4 Answers4

5

As stated by the C# reference, the precision is from 15 to 16 digits (depending on the decimal values represented) before or after the decimal point.

In short, you are right, it depends on the values before and after the decimal point.

For example:

  • 12345678.1234567D //Next digit to the right will get rounded up
  • 1234567.12345678D //Next digit to the right will get rounded up

Full sample at: http://ideone.com/eXvz3

Also, trying to think about double value as fixed decimal values is not a good idea.

jorgebg
  • 6,560
  • 1
  • 22
  • 31
2

You're both wrong. A normal double has 53 bits of precision. That's roughly equivalent to 16 decimal digits, but thinking of double values as though they were decimals leads to no end of confusion, and is best avoided.

That said, you are much closer to correct than your colleague--the precision is relative to the value being represented; sufficiently large doubles have no fractional digits of precision.

For example, the next double larger than 4503599627370496.0 is 4503599627370497.0.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
0

C# doubles are represented according to IEEE 754 with a 53 bit significand p (or mantissa) and a 11 bit exponent e, which has a range between -1022 and 1023. Their value is therefore

p * 2^e

The significand always has one digit before the decimal point, so the precision of its fractional part is fixed. On the other hand the number of digits after the decimal point in a double depends also on its exponent; numbers whose exponent exceeds the number of digits in the fractional part of the significand do not have a fractional part themselves.

What Every Computer Scientist Should Know About Floating-Point Arithmetic is probably the most widely recognized publication on this subject.

Nicola Musatti
  • 17,834
  • 2
  • 46
  • 55
0

Since this is the only question on SO that I could find on this topic, I would like to make an addition to jorgebg's answer.

According to this, precision is actually 15-17 digits. An example of a double with 17 digits of precision would be 0.92107099070578813 (don't ask me how I got that number :P)

Vlad
  • 1
  • 1
  • How did you get this number? – v01pe Dec 06 '19 at 13:53
  • 1
    @v01pe If you need to know... It was randomly generated for me by a test I had for a function that's supposed to serialize a small range of doubles into a ulong. Since the doubles that I was trying to serialize were from slightly less than 1.0 to slightly less than 10.0, I figured multiplying the value of the double by 10^16 should should give me a ulong that I can then divide by 10^16 to retrieve the original value. This number is the value displayed by the debugger for the first example I found that would not work. In the meantime, I found a better way to do the serialization. Now you know. – Vlad Dec 09 '19 at 13:00