其他分享
首页 > 其他分享> > c – 所有整数值都完美地表示为双精度数吗?

c – 所有整数值都完美地表示为双精度数吗?

作者:互联网

参见英文答案 > Representing integers in doubles                                    5个
我的问题是,是否保证所有整数值都具有完美的双重表示.

请考虑以下打印“相同”的代码示例:

// Example program
#include <iostream>
#include <string>

int main()
{
  int a = 3;
  int b = 4;
  double d_a(a);
  double d_b(b);

  double int_sum = a + b;
  double d_sum = d_a + d_b;

  if (double(int_sum) == d_sum)
  {
      std::cout << "Same" << std::endl;
  }
}

这是否适用于任何架构,任何编译器,a和b的任何值?将我转换为double的任何整数,总是表示为i.0000000000000而不是,例如,i.000000000001?

我尝试了其他一些数字并且它总是如此,但无法找到关于这是巧合还是设计的任何信息.

注意:这与this question(除了语言)不同,因为我添加了两个整数.

解决方法:

免责声明(由Toby Speight建议):尽管IEEE 754表示很常见,但允许实现使用满足语言要求的任何其他表示.

双精度以尾数* 2 ^指数的形式表示,即一些位用于双数的非整数部分.

             bits        range                       precision
  float        32        1.5E-45   .. 3.4E38          7- 8 digits
  double       64        5.0E-324  .. 1.7E308        15-16 digits
  long double  80        1.9E-4951 .. 1.1E4932       19-20 digits

Schematic of IEEE 754 double type

分数中的部分也可以通过使用指数去除点后的所有数字来表示整数.

例如. 2,9979·10 ^ 4 = 29979.

由于公共int通常是32位,因此您可以将所有整数表示为double,但对于64位整数,当然这不再是真的.更确切地说(正如LThode在评论中指出的那样):IEEE 754双精度可以保证最多53位(52位有效数和隐含前导1位).

答案:32位整数是,64位整数不.

(这对于服务器/桌面通用CPU环境是正确的,但其他体系结构可能表现不同.)

Malcom McLean提出的实用答案:对于几乎所有可能在现实生活中计算事物的整数,64位双精度数是一个足够的整数类型.

对于经验倾向,请尝试this

#include <iostream>
#include <limits>
using namespace std;

int main() {
    double test;
    volatile int test_int;
    for(int i=0; i< std::numeric_limits<int>::max(); i++) {
        test = i;
        test_int = test;

        // compare int with int:
        if (test_int != i)
            std::cout<<"found integer i="<<i<<", test="<<test<<std::endl;
    }
    return 0;
}

Success time: 0.85 memory: 15240 signal:0

Subquestion:
关于分数差异的问题.是否有可能有一个整数转换为一个double,它正好偏离正确的值一小部分,但由于四舍五入而转换回相同的整数?

答案是否定的,因为任何来回转换为相同值的整数实际上代表double中的相同整数值.对我来说,最简单的解释(由ilkkachu建议)就是使用指数2 ^指数,步长必须始终是2的幂.因此,除了最大的52(1符号)位整数之外,从不存在两个距离小于2的双值,这解决了舍入问题.

标签:c,precision,standards,double,ieee-754
来源: https://codeday.me/bug/20190923/1815361.html