1

In C#:

Console.WriteLine(1.2d - 1.0d); 

produces 0.2.

In python 3:

print(1.2 - 1.0) 

produces 0.19999999999999996.

My goal is to write fast code in C# that produces the same floating point results as python 3. I'm obviously interested in any and all float arithmetic, not just the example above.

What is the most practical way to achieve that? Is there a library I can use?

In addition, I would like to understand, what accounts for this difference. Both representations are 64 bit, and both seem to be based on IEEE. So what is different about these implementations that make them produce different results?

References:

4
  • I suggest you start by looking at the bitwise representation of the result, rather than the string representation - until you've done that, there's no evidence that the subtraction results are actually any different. But you also need to understand that in C# the JIT compiler is allowed to use more precise representations in some arithmetic, e.g. using 80 bit intermediate results while performing multiple 64 bit operations. If you want bit-compatible arithmetic between platforms, that's going to be tricky. Commented Feb 22, 2017 at 10:54
  • @JonSkeet, thank you, this is bad news ;( Commented Feb 22, 2017 at 10:54
  • FWIW, in Python 2 0.2 is printed, but it's the same underlying bit pattern, as can be seen using d = 1.2 - 1.0; print(format(d, '0.60f')) which prints 0.199999999999999955591079014993738383054733276367187500000000 in either version. Commented Feb 22, 2017 at 11:05
  • @JonSkeet I'd like to thank you for your advice to look at the binary representation Commented Feb 22, 2017 at 11:16

1 Answer 1

2

As Jon Skeet points out in the comments, you need to compare the bit representations. Try this in C#:

Console.WriteLine($"{BitConverter.DoubleToInt64Bits(1.2d - 1.0d):X}"); 

result: 3FC9999999999998.

Now in python 3 (courtesy of this answer):

import struct import binascii print(binascii.hexlify(struct.pack('>d', (1.2 - 1.0))).decode()) 

result: 3fc9999999999998

As you can see, the result is the same.

Sign up to request clarification or add additional context in comments.

4 Comments

In this case, yes - but the other aspect of my comment about what happens to intermediate results when you have complex computations may still be relevant, I'm afraid. (It may happen in Python as well, but the precise rules for when it happens are implementation-specific in .NET.)
@JonSkeet understood. On an unrelated note, can you tell me, how can be explained that the same bits are printed out as different numbers? Are there any particular (well-known) algorithms that are used for formatting doubles for output?
For .NET, calling double.ToString() is equivalent to using the G format specifier - see details there. I have a class you can use which will print out the exact value of a double - I don't know whether there's an equivalent in Python.
@JonSkeet, thank you so much again! This is very helpful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.