long double increment operator not working on large numbers

╄→гoц情女王★ 提交于 2019-12-11 02:14:43

问题


I'm converting a C++ system from solaris (SUN box and solaris compiler) to linux (intel box and gcc compiler). I'm running into several problems when dealing with large "long double" values. (We use "long double" due to some very very large integers... not for any decimal precision). It manifests itself in several weird ways but I've simplified it to the following program. It's trying to increment a number but doesn't. I don't get any compile or runtime errors... it just doesn't increment the number.

I've also randomly tried a few different compiler switches, (-malign-double and -m128bit-long-double with various combinations of these turned on and off), but no difference.

I've run this in gdb too and gdb's "print" command shows the same value as the cout statement.

Anyone seen this behavior?

Thanks

compile commands

$ /usr/bin/c++ --version
c++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)

$ /usr/bin/c++ -g -Wall -fPIC   -c SimpleLongDoubleTest.C   -o SimpleLongDoubleTest.o

$ /usr/bin/c++ -g SimpleLongDoubleTest.o   -o SimpleLongDoubleTest

$ ./SimpleLongDoubleTest
Maximum value for long double: 1.18973e+4932
digits 10 = 18
ld = 1268035319515045691392
ld = 1268035319515045691392
ld = 1268035319515045691392
ld = 1268035319515045691392
ld = 1268035319515045691392

SimpleLongDoubleTest.C

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <limits>
#include <iomanip>

int main( int argc, char* argv[] )
{
    std::cout << "Maximum value for long double: " 
              << std::numeric_limits<long double>::max() << '\n';

    std::cout << "digits 10 = " << std::numeric_limits<long double>::digits10 
              << std::endl;

    // this doesn't work  (there might be smaller numbers that also doen't work...
    // That is, I'm not sure the exact number between this and the number defined
    // below where things break)
      long double ld = 1268035319515045691392.0L ;

    // but this or any smaller number works (there might be larger numbers that
    // work... That is, I'm not sure the exact number between this and the number
    // defined above where things break)
    //long double ld =  268035319515045691392.0L ;

    for ( int i = 0 ; i < 5 ; i++ )
    {
        ld++ ;

        std::cout << std::setiosflags( std::ios::fixed ) 
                  << std::setprecision( 0 ) 
                  << "ld = "  <<    ld
                  << std::endl ;
    }
}

回答1:


This is expected behavior. Float, double, long double etc. are internally represented in form of (2^exp-bias)*1 + xxxxx, where xxxxx is a N digit binary number, where N=23 for floats, 52 for doubles and possibly 64 for long doubles. When the number grows larger than 2^N, it's no longer possible to add '1' to that variable -- one can only add multiples of 2^(n-N).

It's also possible that your architecture equates long double as double. (even though x86 can use internally 80-bit doubles).

See also Wikipedia article -- 128 bit double is rather an exception than a norm. (sparc supports it).



来源:https://stackoverflow.com/questions/16152536/long-double-increment-operator-not-working-on-large-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!