【问题标题】:Round double to nearest uint64_t将双精度舍入到最近的 uint64_t
【发布时间】:2019-11-29 22:45:06
【问题描述】:

我需要将双精度数四舍五入到最接近的有效uint64_t

所以

uint64_t Round(double);
Round(std::numeric_limits<double>::max())==std::numeric_limits<uint64_t>::max();
Round(std::numeric_limits<double>::lowest())==std::numeric_limits<uint64_t>::min();
Round(1.1)==1;

Round 应该等价于但对于 uint64_t 而不是有符号整数

auto Round(double d){
    std::fesetround(FE_TONEAREST);
    return llrint(d);
}

std && boost 中是否有任何功能可以实现这一点?

【问题讨论】:

  • 四舍五入到最接近的uint64_t 与四舍五入到最接近的整数有何不同?我唯一能想到的是它不适合uint64_t,在这种情况下你会做什么,究竟是什么?。
  • @ScottHunter 这在第一个描述的测试用例中有所介绍:最大值 double(远大于最大值 uint64_t)应该一直向下舍入到最大值 uint64_t

标签: c++ floating-point rounding


【解决方案1】:

double 不能保存 uint64_t 的所有值,因为它们通常都是 64 位,而double 需要为指数预留位。

不过,要得到最接近的值并不难:

uint64_t Round(double x){
    double rounded=round(x);
    if(rounded<0)
        return 0;
    if(rounded>=pow(2,64))
       return std::numeric_limits<uint64_t>::max();
    return static_cast<uint64_t>(rounded);
}

【讨论】:

  • 请注意溢出检查不正确。 See here 解释一下。
  • double 通常是 64 位,但也可以有不同的大小。例如,在某些 Arduinos 上它是 32 位的。
  • pow 的一些实现不好,所以pow(2, 64) 可能不正确。替代方案包括 C++ 2017 中的 0x1p64(UINT64_MAX/2+1) * 2.18446744073709551616.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2021-09-12
  • 2023-03-03
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
相关资源
最近更新 更多