0

I'm trying to read in two numbers, and display the absolute difference between them. The numbers get ridiculously large, so I had to switch from LONG to LONG DOUBLE and just display them with 0 precision on the decimal. My issue is that with the number listed in the subject, when I scan it into a long double from a string's c_str either in the scan the last digit is being dropped, or more likely the display of the long double is dropping it. 9223372036854775807 - 1 should be 9223372036854775806 but instead it's displaying 9223372036854775800, and when I stop to inspect the long double with the 9223372036854775807 in it, it just shows me "9.2233720368547758e+018"

I would blame this all on a 2 bit processor, but it seems on a 64 bit it's still printing the wrong answer. Has anyone got any way to preserve the entire number? my includes are stripped of characters that seemed to be messing with the html parser.

#include iostream
#include string
#include math.h


using namespace std;

int main () {


    string line;
    std::getline(std::cin, line);


    while ( std::cin )
    {

      long double n, m, o;


      sscanf ((char *)line.c_str(),"%Lf %Lf",&n, &m);

      if(n>=m)
      {
         o = n - m;
      }
      else
      {
          o = m-n;
      }
      char buffer[100000];

    sprintf( buffer , "%0.0Lf\0", o); 

      cout << buffer << endl;
      std::getline(std::cin, line);
    }


  return 0;
}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
OthelloNYC
  • 13
  • 3
  • 3
    Note that on many compilers today, `long double` isn't any bigger than `double`. So it's still only 53 bits of precision. – Mysticial Feb 16 '12 at 00:05
  • 1
    just FYI you should use cmath instead of math.h and either prefix (recommended) every from the standard library std:: or don't prefix anything. – 111111 Feb 16 '12 at 00:10
  • If you need extremely large numbers, don't use the built-in types, use a special class that allows you to have infinitely large numbers(limited only by your system resources). Do a search for "C++ big int" and you will find many examples. – Benjamin Lindley Feb 16 '12 at 00:12
  • Mystical is correct. For MSVC, `long double` uses the same underlying 64-bit type as `double`. That's not the case for GCC, which uses the 80 bit type (the size of the C type will be 96 or 128 bits depending on the padding used). More details: http://stackoverflow.com/a/7136886/12711 – Michael Burr Feb 16 '12 at 00:13
  • You'll have odds for an 80-bit long double format in 32-bit code. Not 64-bit code. – Hans Passant Feb 16 '12 at 00:15

3 Answers3

2

long double is not required to provide more precision than double. However, even if it does, you have to tell the compiler that the literal is a long double. Without a decimal point, the compiler will assume 9223372036854775807 is some kind of integer. So you need to write it as 9223372036854775807.0L.

And again, the compiler doesn't have to give you more precision than a double. So don't be too surprised if you don't get any added precision.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
2

I would stop using long double and use long long if your compiler supports it. You said you had previously been using long so I don't think you were storing fractional parts; if that is correct, then long long would be what you want, not long double. I tested your code with long long on MSVC++ 2010 and it gave the expected output.

And as Mysticial noted, double is the same as long double on many compilers today.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
0

After accept answer.

Floating point numbers have finite precision.

In <cfloat> is LDBL_DIG. This is the number of significant decimal digits that code may read text into a long double and will always print the same digits out again.

The is specified to be at least 10 and is often 15+. 9223372036854775807, with its 18 significant decimal digits certainly exceeds your system's value of LDBL_DIG.

Switching to integer math has a far more limited range. long may not work as LONG_MAX may be as small as 2147483647. Better to use long long which can cope with numbers up to at least 9223372036854775807 - just big enough.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256