2

I am a part of a team which is developing a scientific software, so reproducibility of our results is our highest priority. We noticed that depends on which OS was used, the software generates slightly different results. I found out that in rare occasions exp and log functions give results with discrepancy on last bit of double.

Here I have an example on c#, but the same can be reproduced on at least c++ or python. All tests were done on the same machine.

using System;

namespace Test {
    public class Program {
        public static void Main() {
            byte[] input = { 14, 243, 143, 0, 124, 41, 85, 64 };
            double inputD = BitConverter.ToDouble(input, 0);
            double outputD = Math.Exp(inputD);
            byte[] output = BitConverter.GetBytes(outputD);

            Console.WriteLine("Math.Exp(" + inputD + "\thex: " + BitConverter.ToString(input).Replace("-", " ") + ")\t=\t" +
                              outputD + "\thex: " + BitConverter.ToString(output).Replace("-", " "));

            input = new byte[] { 198, 77, 75, 30, 56, 151, 18, 65 };
            inputD = BitConverter.ToDouble(input, 0);
            outputD = Math.Log(inputD);
            output = BitConverter.GetBytes(outputD);

            Console.WriteLine("Math.Log(" + inputD + "\thex: " + BitConverter.ToString(input).Replace("-", " ") + ")\t=\t" +
                              outputD + "\thex: " + BitConverter.ToString(output).Replace("-", " "));
        }
    }
}

Windows 10.0.15063, mono 5.2.0:

Math.Exp(84.6481934934384 hex: 0E F3 8F 00 7C 29 55 40) = 5.7842004815199E+36 hex: 9A 64 2E 68 FC 67 91 47
Math.Log(304590.029584136 hex: C6 4D 4B 1E 38 97 12 41) = 12.6267219860911 hex: 14 E4 43 B4 E1 40 29 40

Ubuntu 16.04, mono 5.2.0.224:

Math.Exp(84.6481934934384 hex: 0E F3 8F 00 7C 29 55 40) = 5.7842004815199E+36 hex: 99 64 2E 68 FC 67 91 47
Math.Log(304590.029584136 hex: C6 4D 4B 1E 38 97 12 41) = 12.6267219860911 hex: 15 E4 43 B4 E1 40 29 40

Could you suggest any ideas how to deal with it? How to make such fundamentals behave in the same way on different OS?

Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
pgs
  • 153
  • 10
  • I don't see a difference in your post. –  Oct 16 '17 at 15:34
  • 2
    Are you sure it doesn't have to do with different hardware? – p.s.w.g Oct 16 '17 at 15:34
  • @Pi See `9A` vs `99` and `14` vs `15` in the results. (You have to scroll to the right to see it). – p.s.w.g Oct 16 '17 at 15:35
  • @p.s.w.g the same machine was used. Sorry, forgot to write this important detail – pgs Oct 16 '17 at 15:37
  • 1
    Are you sure it was the OS and not the compiler? If using `g++` on Ubuntu then you should also use `g++` on Windows (preferably with the same version). Make sure your tests isolate the **only** difference as the OS before coming to that conclusion. – cdarke Oct 16 '17 at 15:39
  • https://stackoverflow.com/questions/6683059/is-floating-point-math-consistent-in-c-can-it-be – SushiHangover Oct 16 '17 at 15:49
  • @SushiHangover it's not about float - all operations are done with double – pgs Oct 16 '17 at 15:51
  • @pgs I believe nearly every answer in the linked question applies equally well to `float` and `double` values. Both are floating-point data types. – p.s.w.g Oct 16 '17 at 15:55
  • 1
    along with what's said in the linked SO topic, note that trascendental functions are not required to be exactly rounded (relative to current rounding mode) even on iee754 ( due to *table maker dilemma*), so implementations can vary. – Massimiliano Janes Oct 16 '17 at 15:56
  • @pgs A `double` is a float point number – SushiHangover Oct 16 '17 at 15:58
  • @SushiHangover I am fully agree with you. – pgs Oct 16 '17 at 16:07
  • Can you post c++ code example as well? –  Oct 16 '17 at 18:38
  • @Pi but I have already mentioned it here https://gist.github.com/pgsin/2816cf5b69cd3c9b6b4ccc55ac99c02f – pgs Oct 16 '17 at 20:38

0 Answers0