【问题标题】:Rotate Right operation on integer data using floating point operations?使用浮点运算对整数数据进行右移运算?
【发布时间】:2011-05-09 04:58:09
【问题描述】:

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

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

【问题讨论】:

    标签: 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 硬件内部进行快速移位操作,即使整数硬件没有快速移位也是如此。

    【讨论】:

      猜你喜欢
      • 2013-06-12
      • 2014-01-10
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 2016-10-15
      相关资源
      最近更新 更多