3

Immediately warn you that this is a difficult task.

There is a test. The test was the result of parsing a large problem to a bug in which we encountered at work. Construction __ attribute__((noinline)) prohibits the compiler to do the substitution function (for optimizations to something there not imploded). This is the easiest way to optimize guaranteed not to kill an interesting situation.

#include <stdio.h>

double d = 5436277361664796672.000000;
long long ll = 5436277361664796253LL;

int __attribute__((noinline))
func1 (void)
{
  double d1 = (double)ll;

  if (d > d1)
    return 1;
  else
    return 0;
}

int __attribute__((noinline))
func2 (void)
{
  if (d > (double)ll)
    return 1;
  else
    return 0;
}

int
main (void)
{
  printf ("%d %d\n", func1(), func2());
  return 0;
}

I ran this test on intel and sparc. Gcc used in a mode with optimizations and without optimizations. Obtained the following results:

sparc: "gcc" printed "0 0"
sparc: "gcc -O2" printed "0 0"
intel: "gcc" printed "0 1"
intel: "gcc -O2" printed "1 1"

What is the cause differences? Anyway in the analysis situation would be useful to be able to repeat it all myself, but, of course, almost no one has the possibility to run this code on sparc. Instead sparc can try to run under Windows using microsoft or borland C compiler. I do not know what they will be given the results, but in any case something does not match with anything (because we see three different results)

Edit 1 _attribute_ ((noinline)) - an extension of the compiler gcc (forgot to write about it). Therefore VisualStudio can not compile it.

Amazing User
  • 3,473
  • 10
  • 36
  • 75
  • That optimizations change the result indicates presence of undefined behavior, but I can't yet pin down where you'd get UB. –  Feb 18 '14 at 21:45
  • You may want to check the size of the variables. Check this question: http://stackoverflow.com/questions/7279504/long-and-long-long-bit-length – Snake Sanders Feb 18 '14 at 21:49
  • Do you believe that it is specified how integers are converted to floating point numbers? If so, where and how? The point is that with optimizations the result is consistent, as you would expect. – Kerrek SB Feb 18 '14 at 22:02
  • @delnan I don't think that is true. Unspecified perhaps. – David Heffernan Feb 18 '14 at 22:21
  • @DavidHeffernan It's certainly possible that there's another cause, but UB is the most likely cause. Also, is "unspecified" a technical term from the standard? Because "undefined behavior" is, and things that are not specific in the standard (in an informal sense) invoke undefined behavior (in a formal sense). –  Feb 18 '14 at 22:30
  • @delnan http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior – David Heffernan Feb 18 '14 at 22:33
  • @DavidHeffernan Thanks, I came across that once but forgot about it. –  Feb 18 '14 at 22:36

2 Answers2

1

I note that the declaration of the double constant has 19 significant figures which is more precision than can be represented by a IEEE double (which allows 15 to 17 significant figures). So d cannot hold 5436277361664796672.000000 exactly.

The two constant definition strings become different at the 16th digit, so you are in the region where the inaccuracies in the double are of the same magnitude as the difference between these two numbers. Hence the comparison cannot be relied upon.

I do not know if the C++ standard specifies what happens when an over-precise string is converted to a double, but I would not be surprised if the exact result was either undefined or implementation-dependent.

Tim Bergel
  • 499
  • 3
  • 9
0

Seems solved the problem. In general, all written correctly. But actually works correctly sparc version. Because standard to convert int64-> float64 must be a loss of precision. And in the code when you convert (for intel) int64-> float80 loss occurs. Ie intel-based code works with higher accuracy , but it is in contradiction with the standard.

Perhaps it is some sort of agreement for the platform Intel, which is permissible by default to work this way. Surely there are some options on which the code runs in strict accordance with the standard (but becomes slower)

Amazing User
  • 3,473
  • 10
  • 36
  • 75