Man*_*eel 2 c++ floating-point bit-manipulation
unsigned GetLowestBitPos(unsigned value)
{
double d = value ^ (value - !!value);
return (((int*)&d)[1]>>20)-1023; // This is what I really need help understanding.
}
Run Code Online (Sandbox Code Playgroud)
在我看来,代码将一个double转换为指向整数的指针.我不确定[1]的用途是什么.然后看起来我们向右移位了20位
我将不胜感激任何有关此代码的帮助.我已经用C++编程了一段时间,并且我正在尝试为可编程逻辑控制器(PLC)编写逻辑,以便在可能的情况下执行相同的操作.
谢谢你的帮助
让我们一步一步迈出这一步.第一:
double d = value ^ (value - !!value);
Run Code Online (Sandbox Code Playgroud)
如果value = 0,则计算结果为0 ^(0 - 0),因此d为0.如果value != 0,则计算结果为^(value - 1).这具有将最低的一位和最低的零位设置为一,并将所有其他位设置为零的效果.例如:
value = 010100100
d = 000000111
Run Code Online (Sandbox Code Playgroud)
这是因为(value - 1)是一样的value,所不同的是零个比特的最低串成为一体,而下一个比特变为零,由于携带
value = 010100100
value - 1 = 010100011
XOR value = 000000111
Run Code Online (Sandbox Code Playgroud)
无论如何,d都加载了这个浮点值.下一行:
return (((int*)&d)[1]>>20)-1023;
Run Code Online (Sandbox Code Playgroud)
这将提取浮点指数,并加回偏差.请注意,这假设有一个小端系统,例如x86; 在你需要使用的大端系统上[0].它还假设ints 的大小,并且doubles- 特别是,它假设32位整数,64位IEEE浮点数用于双精度.
这里的关键是非非规范化的IEEE浮点值(以及double中的32位int将始终是非非规范化的)最终得到一个看起来有点像的表示1.xxxxxxxx * 2^(e-1023),其中xxxxxxxx是小数分量,并且e是指数.由于你已经将那些有意义的位置作为最高位的位,所以exponentend和你正在寻找的值.
也就是说,你可能无法在PLC上使用它 - 尽管它是一个非常聪明的黑客,如果你有一个硬件FPU,它甚至可以远程高效; 甚至在x86系统上也有更快的内置整数运算.在这个SO问题中还有许多其他技术; 你可能会在那里找到一个更快的.您的PLC也可能具有内置操作以在一条指令中执行此操作.
| 归档时间: |
|
| 查看次数: |
320 次 |
| 最近记录: |