使用浮点运算对整数数据执行向右旋转操作



我想取一个带有无符号整数表示的值,并以某种方式使用浮点运算执行右移位操作。

看看这里使用的聪明: http://en.wikipedia.org/wiki/Fast_inverse_square_root这使用魔术值和一些技巧来使用整数运算对浮点数执行操作。 我想要的是相反的;我使用的硬件针对浮点进行了大量优化,但在整数运算方面表现不佳。 该算法是sha256,它大量使用右旋操作。

我想

到了两种方法:

  • 获取保存整数的位,将它们填充到一个期望保持相同位数的浮点数的变量中,并对这些位进行操作,就好像它们是浮点数一样。希望硬件具有一些浮点运算,这些浮点运算对这些位的操作方式与 SHA256 使用的整数运算相同。
  • 整数填充到具有更多位的浮点变量中(例如,将 Int32 放入 Double,它可以容纳 53 位而不会丢失精度),然后使用数学运算实现右旋操作。

第一种选择不太可能奏效。如果您的硬件基于 IEEE 754 浮点标准(浮点表示的最常见标准),则浮点数将存储为位域;例如,双精度有一个符号位、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硬件内的快速移位操作,即使整数硬件没有快速移位。

最新更新