我正在寻找一种合理有效的方法来确定浮点值(double)是否可以由整数数据类型(long,64位)精确表示.
我最初的想法是检查指数是否0(或更确切地说127).但这不会起作用,因为2.0e = 1 m = 1 ......
基本上,我被卡住了.我有一种感觉,我可以使用位掩码做到这一点,但我现在还没有理解如何做到这一点.
那么我怎样才能检查一个double是否完全可以表示为long?
谢谢
假设我有一个接受64位整数的函数,我想用一个double带有任意数值的函数调用它(即它的幅度非常大,甚至无限大):
void DoSomething(int64_t x);
double d = [...];
DoSomething(d);
Run Code Online (Sandbox Code Playgroud)
C++ 11标准中[conv.fpint]的第1段说明了这一点:
可以将浮点类型的prvalue转换为整数类型的prvalue.转换转发; 也就是说,丢弃小数部分.如果截断的值无法在目标类型中表示,则行为未定义.
因此,d上面有许多值会导致未定义的行为.我希望转换为饱和,因此大于std::numeric_limits<int64_t>::max()(kint64max在下面称为)的值
(包括无穷大)将成为该值,并且与最小可表示值类似.这似乎是一种自然的方法:
double clamped = std::min(d, static_cast<double>(kint64max));
clamped = std::max(clamped, static_cast<double>(kint64min));
DoSomething(clamped);
Run Code Online (Sandbox Code Playgroud)
但是,标准的下一段说明了这一点:
可以将整数类型或无范围枚举类型的prvalue转换为浮点类型的prvalue.如果可能,结果是准确的.如果要转换的值在可以表示的值范围内,但该值无法准确表示,则它是实现定义的下一个较低或较高可表示值的选择.
所以clamped可能仍然存在kint64max + 1,行为可能仍未定义.
什么是最简单的便携式方式来做我正在寻找的东西?奖励积分,如果它也优雅地处理NaNs.
更新:更确切地说,我希望以下内容对于int64_t SafeCast(double)解决此问题的
函数都是如此:
对于任何double d,调用SafeCast(d)不会根据标准执行未定义的行为,也不会抛出异常或以其他方式中止.
对于d范围内的任何双倍[-2^63, 2^63),
SafeCast(d) == static_cast<int64_t>(d).也就是说,SafeCast在定义后者的任何地方都同意C++的转换规则.
任何双d >= 2^63,SafeCast(d) == kint64max.
任何双d < …
我正在编写一段代码,我必须将其从double转换为float值.我正在使用boost :: numeric_cast进行此转换,这将提醒我任何溢出/下溢.但是我也有兴趣知道这种转换是否会导致一些精确损失.
例如
double source = 1988.1012;
float dest = numeric_cast<float>(source);
Run Code Online (Sandbox Code Playgroud)
产生具有价值1988.1的dest
有没有什么方法可以检测到这种精确损失/舍入
c++ floating-point rounding-error rounding floating-accuracy