相关疑难解决方法(0)

如何检查float是否可以精确表示为整数

我正在寻找一种合理有效的方法来确定浮点值(double)是否可以由整数数据类型(long,64位)精确表示.

我最初的想法是检查指数是否0(或更确切地说127).但这不会起作用,因为2.0e = 1 m = 1 ......

基本上,我被卡住了.我有一种感觉,我可以使用位掩码做到这一点,但我现在还没有理解如何做到这一点.

那么我怎样才能检查一个double是否完全可以表示为long?

谢谢

c double ieee-754

15
推荐指数
2
解决办法
3816
查看次数

如何在避免未定义行为的同时将任意双精度转换为整数?

假设我有一个接受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)解决此问题的 函数都是如此:

  1. 对于任何double d,调用SafeCast(d)不会根据标准执行未定义的行为,也不会抛出异常或以其他方式中止.

  2. 对于d范围内的任何双倍[-2^63, 2^63), SafeCast(d) == static_cast<int64_t>(d).也就是说,SafeCast在定义后者的任何地方都同意C++的转换规则.

  3. 任何双d >= 2^63,SafeCast(d) == kint64max.

  4. 任何双d < …

c++ type-conversion undefined-behavior language-lawyer

13
推荐指数
1
解决办法
1438
查看次数

从double转换为float时检测精度损失

我正在编写一段代码,我必须将其从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

7
推荐指数
2
解决办法
4006
查看次数