规范化一个浮点数
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
我的 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