长双增量运算符不适用于大数 [英] long double increment operator not working on large numbers

查看:108
本文介绍了长双增量运算符不适用于大数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将C ++系统从solaris(SUN框和solaris编译器)转换为linux(intel框和gcc编译器).在处理较大的长双精度"值时,我遇到了几个问题. (由于某些非常大的整数,我们使用"long double" ...不适用于任何十进制精度).它以几种怪异的方式表现出来,但我已将其简化为以下程序.它正在尝试增加一个数字,但没有.我没有任何编译或运行时错误……只是没有增加数量.

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.

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

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.

我也在gdb中运行了该命令,gdb的"print"命令显示的值与cout语句相同.

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

有人看到过这种行为吗?

Anyone seen this behavior?

谢谢

$ /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 ;
    }
}

推荐答案

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

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).

您的体系结构也有可能将long double等同为double. (即使x86可以在内部使用80位双打).

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

另请参见 Wikipedia文章-128位双精度字是一个例外,而不是一种规范. (sparc支持).

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

这篇关于长双增量运算符不适用于大数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆