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
对所有int
s 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】:
不,不是。该标准没有说明int
和double
的相对大小。
如果 int
是 64 位整数,double
是标准 IEEE 双精度,那么对于大于 2^53
的数字,它已经失败了。
也就是说,int
在当今的大多数环境中仍然是 32 位的。所以它在很多情况下仍然成立。
【讨论】:
在什么系统中 int 有 64 位? windows 和 linux 都是 32 位的。 我不认为 C 表示 IEEE 双精度。它只是说双精度;意味着浮点精度的两倍。所以 64 位 int 可能完全适合 double(显然不能保证) @JohannesSchaub-litb 我听说过一些具有 64 位int
s 的 linux 发行版。但那是我从休息室得到的二手信息。
@pm100:我不认为 C 说 double
的精度是浮点数的两倍,它们可能是相同的大小。但是,Mysticial 的帖子是正确的。 “如果... double 是标准的 IEEE 双精度...”
确实,我见过一个使用双精度实现float
和double
的编译器(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)>' 的隐式实例化