long double increment operator不能处理大数字

时间:2013-04-22 16:55:09

标签: c++ linux gcc double long-integer

我正在将一个C ++系统从solaris(SUN box和solaris编译器)转换为linux(intel box和gcc编译器)。在处理大的“long double”值时,我遇到了几个问题。 (由于一些非常大的整数,我们使用“long double”...不是任何小数精度)。它以几种奇怪的方式表现出来,但我已将其简化为以下程序。它试图增加一个数字,但没有。我没有得到任何编译或运行时错误......它只是没有增加数字。

我还随机尝试了一些不同的编译器开关,(-malign-double和-m128bit-long-double,其中各种组合打开和关闭),但没有区别。

我也在gdb中运行它,gdb的“print”命令显示与cout语句相同的值。

有人见过这种行为吗?

由于

编译命令

$ /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 个答案:

答案 0 :(得分:3)

这是预期的行为。浮点数,双精度,长双精度等在内部以(2 ^ exp-bias)* 1 + xxxxx的形式表示,其中xxxxx是N位二进制数,其中N = 23表示浮点数,52表示双精度数,可能64表示长数双打。当数字增长大于2 ^ N时,不再可能为该变量添加“1” - 只能添加2 ^(n-N)的倍数。

您的架构也可能将long double视为double。 (即使x86可以在内部使用80位双精度数。)

另见Wikipedia article - 128位双重是一个例外而非常态。 (sparc支持它)。