c++ - 比较一个 32 位 float 和一个 32 位整数而不转换为 double 值,当任一值可能太大而无法完全适合另一种类型时

标签 c++ floating-point arm precision

我有一个 32 位 float f我需要转换为 32 位无符号整数的数字(已知为正数)。它的大小可能太大而不适合。此外,下游计算需要一些净空。我可以计算最大可接受值 m作为 32 位整数。如果 f <= m,我如何在受约束的 32 位机器 (ARM M4F) 上有效地确定 C++11数学上。请注意,这两个值的类型不匹配。以下三种方法各有其问题:

  • static_cast<uint32_t>(f) <= m :我认为这会触发未定义的行为,如果 f不适合 32 位整数
  • f <= static_cast<float>(m) : 如果 m太大而无法准确转换,转换后的值可能大于 m使得后续比较在某些边缘情况下会产生错误的结果
  • static_cast<double>(f) <= static_cast<double>(m) : 在数学上是正确的,但需要强制转换为 double 并使用 double,出于效率原因我想避免这种情况

当然必须有一种方法可以将整数直接转换为具有指定舍入方向的 float ,即保证结果不超过输入的数量级。我更喜欢 C++11 标准解决方案,但在最坏的情况下,平台内在函数也符合条件。

最佳答案

我认为您最好的选择是针对特定平台。 2³² 可以用 float 精确表示。检查 f 是否太大而根本无法容纳,然后转换为无符号并检查 m

const float unsigned_limit = 4294967296.0f;
bool ok = false;
if (f < unsigned_limit)
{
    const auto uf = static_cast<unsigned int>(f);
    if (uf <= m)
    {
        ok = true;
    }
}

不喜欢双重比较,但很清楚。

如果 f 通常明显小于 m(或通常明显大于),可以针对 float(m)*0.99f 进行测试(分别为float(m)*1.01f),然后在异常情况下做精确比较。这可能只有在分析表明性能提升值得额外的复杂性时才值得这样做。

关于c++ - 比较一个 32 位 float 和一个 32 位整数而不转换为 double 值,当任一值可能太大而无法完全适合另一种类型时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43862716/

相关文章:

c++ - 在尝试使用递归查找集合的子集总数时,出现段错误

math - float 学有问题吗?

arm - 为什么 Cortex-M4 在链接描述文件中包含 ARM to Thumb 胶水

c++ - 运行 C++ 程序时的 VsCode

c++ - 如何有条件地同时多线程和更新变量?

c# - float.Parse 中丢失的 float 精度

c - 如何开始使用 ARM 处理器?

c++ - NEON:将 int8x16_t 解包为一对 int16x8 并将一对 int16x8_t 打包为 int8x16_t

c++ - 稳定级联阴影映射中的光 View 矩阵

javascript - 如何处理 JavaScript 中的 float 精度?