int->double->int 是不是保证保值?

Posted

技术标签:

【中文标题】int->double->int 是不是保证保值?【英文标题】:Is int->double->int guaranteed to be value-preserving?int->double->int 是否保证保值? 【发布时间】:2012-12-03 22:55:48 【问题描述】:

如果我有一个int,将其转换为double,然后将double 转换回int,我能保证得到与我开始时相同的值吗?换句话说,给定这个函数:

int passThroughDouble(int input)

  double d = input;
  return d;

我保证passThroughDouble(x) == x 对所有ints x 吗?

【问题讨论】:

这取决于 int 的大小,例如对于 64 位整数,这绝对行不通。对于 32 位整数,它可能可以工作。 assert(std::numeric_limits<int>::digits <= std::numeric_limits<double>::digits); - en.cppreference.com/w/cpp/types/numeric_limits/digits @sehe:你的意思是static_assert。 :P @GManNickG 该死。为时已晚修复:) static_assert(std::numeric_limits<int>::digits <= std::numeric_limits<double>::digits, "barf"); 当然,任何名副其实的编译器都会优化对 double 的摆弄,直接返回输入。或者可能不是 - 如果编译器编写者知道结果不能保证:-) 【参考方案1】:

不,不是。该标准没有说明intdouble 的相对大小。

如果 int 是 64 位整数,double 是标准 IEEE 双精度,那么对于大于 2^53 的数字,它已经失败了。


也就是说,int 在当今的大多数环境中仍然是 32 位的。所以它在很多情况下仍然成立。

【讨论】:

在什么系统中 int 有 64 位? windows 和 linux 都是 32 位的。 我不认为 C 表示 IEEE 双精度。它只是说双精度;意味着浮点精度的两倍。所以 64 位 int 可能完全适合 double(显然不能保证) @JohannesSchaub-litb 我听说过一些具有 64 位 ints 的 linux 发行版。但那是我从休息室得到的二手信息。 @pm100:我不认为 C 说 double 的精度是浮点数的两倍,它们可能是相同的大小。但是,Mysticial 的帖子是正确的。 “如果... double 是标准的 IEEE 双精度...” 确实,我见过一个使用双精度实现floatdouble 的编译器(LCC?)。【参考方案2】:

如果我们将考虑限制为浮点类型的“传统”IEEE-754 样式表示,那么当且仅当 double 类型的尾数具有尽可能多的位,因为 int 类型中有非符号位。

经典 IEEE-754 double 类型的尾数是 53 位宽(包括“隐含”的前导位),这意味着您可以精确地表示 [-2^53, +2^53] 范围内的整数。超出此范围的所有内容通常都会丢失精度。

因此,这完全取决于您的 int 与您的 double 相比有多宽。答案取决于具体的平台。对于 32 位 int 和 IEEE-754 double,应该保持相等性。

【讨论】:

数字音频系统依赖于整数到浮点到整数的转换才能工作,否则“世界将停止旋转”。作为一个不得不钻研主题理论并进行一些实际实验的人,我只能说这是正确的答案。

以上是关于int->double->int 是不是保证保值?的主要内容,如果未能解决你的问题,请参考以下文章

未定义模板 'std::__1::function<int (double, double, double, double)>' 的隐式实例化

C++ 将向量<int> 转换为向量<double>

在java中将double与int进行比较是不是有效?

std::pair<vector<int>, double> 的初始化列表

矩阵乘法性能,int vs double

判断字符串到 double/float/int/short/byte 是不是超出范围