当一个值可能太大而无法完全适合另一个类型时,比较一个32位浮点数和一个32位整数而不转换为double [英] Compare a 32 bit float and a 32 bit integer without casting to double, when either value could be too large to fit the other type exactly

查看:161
本文介绍了当一个值可能太大而无法完全适合另一个类型时,比较一个32位浮点数和一个32位整数而不转换为double的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个32位浮点f数字(已知为正数),我需要将其转换为32位无符号整数.它的大小可能太大而无法容纳.此外,存在下游计算需要一定的余量.我可以将最大可接受值m计算为32位整数.如果在数学上f <= m,如何在受限的32位计算机(ARM M4F)上的C ++ 11中有效确定.请注意,两个值的类型不匹配.以下三种方法各有其问题:

I have a 32 bit floating point f number (known to be positive) that I need to convert to 32 bit unsigned integer. It's magnitude might be too large to fit. Furthermore, there is downstream computation that requires some headroom. I can compute the maximum acceptable value m as a 32 bit integer. How do I efficiently determine in C++11 on a constrained 32 bit machine (ARM M4F) if f <= m mathematically. Note that the types of the two values don't match. The following three approaches each have their issues:

  • 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,出于效率原因,我希望避免这种情况
  • static_cast<uint32_t>(f) <= m: I think this triggers undefined behaviour if f doesn't fit the 32 bit integer
  • f <= static_cast<float>(m): if m is too large to be converted exactly, the converted value could be larger than m such that the subsequent comparison will produce the wrong result in certain edge cases
  • static_cast<double>(f) <= static_cast<double>(m): is mathematically correct, but requires casting to, and working with double, which I'd like to avoid for efficiency reasons

肯定有一种方法可以直接将整数转换为具有指定舍入方向的浮点数,即保证结果的大小不超过输入值.我更喜欢C ++ 11标准解决方案,但在最坏的情况下,平台内在函数也可能合格.

Surely there must be a way to convert an integer to a float directly with specified rounding direction, i.e. guaranteeing the result not to exceed the input in magnitude. I'd prefer a C++11 standard solution, but in the worst case platform intrinsics could qualify as well.

推荐答案

我认为您最好的选择是针对特定平台. 2³²可以精确地表示为浮点数.检查f是否太大而根本无法容纳,然后转换为unsigned并对照m进行检查.

I think your best bet is to be a bit platform specific. 2³² can be represented precisely in floating point. Check if f is too large to fit at all, and then convert to unsigned and check against 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;
    }
}

不喜欢双重比较,但是很明显.

Not fond of the double comparison, but it's clear.

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

If f is usually significantly less than m (or usually significantly greater), one can test against float(m)*0.99f (respectively float(m)*1.01f), and then do the exact comparison in the unusual case. That is probably only worth doing if profiling shows that the performance gain is worth the extra complexity.

这篇关于当一个值可能太大而无法完全适合另一个类型时,比较一个32位浮点数和一个32位整数而不转换为double的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆