【问题标题】:Rotate Right operation on integer data using floating point operations?使用浮点运算对整数数据进行右移运算?
【发布时间】:2011-05-09 04:58:09
【问题描述】:
【问题讨论】:
标签:
floating-point
integer
bitwise-operators
【解决方案1】:
想到了两种方法:
- 获取包含整数的位,将它们填充到一个期望包含相同位数的浮点数的变量中,然后对这些位进行操作,就好像它们是浮点数一样。希望硬件有一些浮点运算,对这些位的运算方式与 SHA256 使用的整数运算相同。
- 将整数填充到具有更多位的浮点变量中(例如,将 Int32 放入可以容纳 53 位而不会丢失精度的 Double 中),然后使用数学运算实现右旋转操作。
第一个选项不太可能奏效。如果您的硬件基于 IEEE 754 浮点标准(最常见的浮点表示标准),则浮点数存储为位域;例如,double 有 1 个符号位、11 个指数位和 53 个小数位。不会有任何操作将符号位的值转移到指数位槽之一。然后是具有特殊含义的位模式,并在整个操作中携带该含义,例如 NaN 和无穷大。因此,整个想法可能是行不通的。
我不确定第二种方法是否可行;您将需要完全控制诸如舍入行为之类的事情,并且想要说服自己您的浮点值中有正确的位数,并且您绝对需要大量测试来说服自己它正在得到整个输入范围的预期输出。但是这里有。
一个向右旋转的操作——比如说,x ror y——就这样失败了。设 b 为 x 中的位数。我假设一切都是使用无符号算术完成的,因为它使逻辑更简单。
- 我们从
x ror y开始。
- 这可以表示为右移、左移和 OR,如
(x shr y) or (x shl (b - y))。
- Shr 与除以 2 的幂相同。 Shr 会丢弃掉下端的任何位,因此我们可以使用 floor 函数来模拟它。所以现在我们有了
floor(x / 2^y) or (x shl (b - y))。
- Shl 与乘以 2 的幂相同。 Shl 丢弃掉掉上端的所有位,我们可以通过乘法模 2^b 来模拟。这给了我们
floor(x / 2^y) or ((x * 2^(b - y)) mod 2^b)。
- 由于 shl 和 shr 的结果是不相交的(它们影响结果中的不同位),or 也可以通过加法来完成。所以现在我们有了整个旋转操作的数学符号:
floor(x / 2^y) + ((x * 2^(b - y)) mod 2^b)。
现在只需在 SHA256 执行向右旋转操作的每个位置插入该公式,看看它是否比整数运算更快。这似乎不太可能但并非不可能——将两个具有不同指数的浮点数相加将需要在 FP 硬件内部进行快速移位操作,即使整数硬件没有快速移位也是如此。