" 1<<<< X"和" pow(2,x)"?

时间:2017-11-21 15:40:23

标签: c# unity3d math comparison bit-manipulation

因此,在使用Unity时,我必须使用按位运算符。现在,不要误解我,我完全了解按位运算符的用处,在某些情况下,如果不必编写一堆丑陋的代码就无法替换它。问题更像是...... a和b之间的区别是什么:

double a = 1 << 3;
double b = Math.Pow(2, 3);

根据我对函数和二进制的理解,在这两种情况下,你最终在第四个位置得到1,这等于8 ......什么阻止任何人使用Math.pow而不是按位运算符?它真的会改变什么吗?

2 个答案:

答案 0 :(得分:5)

一般而言,对于大多数语言而言:

pow功能可能效率较低,因为它基本上是通用的,并且可以将任意数量提升到任何功率,因此无法在特殊情况下轻松优化。

位移将直接映射到处理器级操作。

在某些语言中,编译器会看到操作具有恒定的结果并使用它,但是如果有更多的复杂性,那么可能会错过优化。

答案 1 :(得分:4)

  

什么阻止任何人使用Math.pow而不是按位运算符?   它真的会改变什么吗?

有几件事:

  1. (int) Math.Pow(2, y); 不太可读而不是1 << y
  2. 如果(int) Math.Pow(2, y)似乎是2.0**10.0,则
  3. 1023.99999997可能会带来讨厌的错误;我们必须更加精简(int) (Math.Pow(2, y) + 0.5)
  4. 1 << y想要 FPU 计算时,
  5. Math.Pow(2, y)要快得多(大约一个 CPU 勾选)
  6. 1 << 31-2147483648,这在按位逻辑中很方便。如果是(int)Math.Pow(1, y),您可以OverflowException抛出
  7. 1 << y == 1 << (y % 32),例如1 << 40 == 1 << 8 == 256这也很方便。
  8. 如果y 否定 1 << y执行相同的1 << (y % 32)事情,例如1 << -31 == 1 << 2 == 4Math.Pow(2, y)会返回微小的2**y分数(示例中为9.31322574615479E-10
  9. 最后,相当于1 << y

    // y >= 0
    int result = unchecked((int) (Math.Pow(2, y % 32) + 0.5));
    

    希望,这个公式能说明问题。这就是为什么请不要使用Math.Pow代替转移