规范化一个浮点数

Normalize a floating point

我的 PLC(可编程逻辑控制器)无法处理非规范化浮点数。

这是我从 PLC 对面的控制器接收到的数字的一些十六进制表示形式(非规范化): 0x00004180、0x0000C180、0x00006FA0

有人愿意分享一个小代码示例(C++/C# 或类似代码),说明如何对与上述类似的值进行按位规范化吗?我不能对数字使用任何浮点运算,因为它们在 PLC 中无法识别,因此只能进行 HEX/BIN 操作。

精度不是问题。

作为问题评论的后续,如果您想使用定点算法:

非规范化的浮点数小于 2^{-126} 并且小数部分没有隐式设置前导位,所以基本上非规范化的浮点数是 0.mantissa * 2^{-126}

您可以在 int32_t 中获取掩码,然后让您的浮点值等于 int_val * 2^{-126 - 23} = int_val * 2^{-149}。 数字 23 是因为 binary32 格式有 23 位尾数。当然,您会将整数值和指数值存储在不同的变量中。

如果您使用带符号扩展的位移位,将非正规数刷新为零的简单且无分支的方法如下(其中 f 是浮点数的整数重新解释):

int32_t x = f & 0x7F800000; // mask out sign and mantissa
x += 0x7F700000; // overflows unless exponent is zero; MSB now indicates normalized
x >> 31; // sign-extend the MSB to all bits
f &= x; // flush denormals to zero