使用 boost::numeric_cast<double>(long) 是否有目的(即从 long 转换为 double)?

问题描述 投票:0回答:3

我想这个转换不可能失败。所以

boost::numeric_cast<double>(long)
应该产生与普通演员相同的结果。

这是正确的吗?如果是这样,为什么

boost::numeric_cast
比普通演员慢?它正在做某种检查吗?

c++ boost casting numeric-conversion
3个回答
2
投票
static_assert((1ull<<57ull)!=(1+(1ull<<57ull)));
static_assert((double)(1ull<<57ull)==(double)(1+(1ull<<57ull)));

boost numericcast 会抛出这一轮,就像上面的代码一样。

64 位整数可以表示一些 64 位双精度数无法表示的整数。 64 位双精度数在“指数”上花费位。


2
投票

来自文档

缺乏范围保留使得数字类型之间的转换容易出错。对于隐式转换和显式转换(通过

static_cast
)都是如此。
numeric_cast
检测数字类型转换时范围的丢失,如果无法保留范围则抛出异常。

所以看起来 boost 的数字转换做了一些额外的检查,并且可以抛出异常 - 所以它们并不总是与“常规转换”相同。


0
投票

文档

boost::numeric_cast
用于在不损失范围的情况下进行投射
long
的范围不一定比
double
窄,因此
boost::numeric_cast<double>(long)
可能会产生与常规演员不同的结果。例如,一个实现可以具有 96 位
long
和 72 位
double
,且
double
范围非常小。这没有什么问题,它完全符合 C++,因为 C++ 中的类型没有固定大小,只有最小大小。请参阅 C++ 标准规定 int、long 类型的大小是多少?

此外,文档可能有点不清楚,因为

boost::numeric_cast
还阻止从目标类型中无法表示的值进行转换。出于显而易见的原因,浮点值不会将其所有位用于值的重要部分,并会为了精度而交换范围。因此,N 位
double
的精度将小于 N,等于
std::numeric_limits<double>::digits
/
DBL_MANT_DIG
位。对于 IEEE-754 二进制 64,精度为 53 位,因此如果
long
值需要超过 53 位的有效数,那么显然它不能存储在
double
中。例如
0xABCDEF9876543210 = -6066929684898893296
有 60 位有效数,即第一个和最后一个 1 位之间的距离。转换为
double
时,它将四舍五入为
-6066929684898892800
。值的变化意味着
boost::numeric_cast
将失败。有些语言(例如 JavaScript)甚至有一个
MAX_SAFE_INTEGER
常量来表示这个

另请参阅

© www.soinside.com 2019 - 2024. All rights reserved.