因此,在使用Unity时,我必须使用按位运算符。现在,不要误解我,我完全了解按位运算符的用处,在某些情况下,如果不必编写一堆丑陋的代码就无法替换它。问题更像是...... a和b之间的区别是什么:
double a = 1 << 3;
double b = Math.Pow(2, 3);
根据我对函数和二进制的理解,在这两种情况下,你最终在第四个位置得到1,这等于8 ......什么阻止任何人使用Math.pow而不是按位运算符?它真的会改变什么吗?
答案 0 :(得分:5)
一般而言,对于大多数语言而言:
pow功能可能效率较低,因为它基本上是通用的,并且可以将任意数量提升到任何功率,因此无法在特殊情况下轻松优化。
位移将直接映射到处理器级操作。
在某些语言中,编译器会看到操作具有恒定的结果并使用它,但是如果有更多的复杂性,那么可能会错过优化。
答案 1 :(得分:4)
什么阻止任何人使用Math.pow而不是按位运算符? 它真的会改变什么吗?
有几件事:
(int) Math.Pow(2, y);
不太可读而不是1 << y
(int) Math.Pow(2, y)
似乎是2.0**10.0
,则1023.99999997
可能会带来讨厌的错误;我们必须更加精简(int) (Math.Pow(2, y) + 0.5)
1 << y
想要 FPU 计算时,Math.Pow(2, y)
要快得多(大约一个 CPU 勾选)
1 << 31
是-2147483648
,这在按位逻辑中很方便。如果是(int)Math.Pow(1, y)
,您可以OverflowException
抛出1 << y == 1 << (y % 32)
,例如1 << 40 == 1 << 8 == 256
这也很方便。y
否定 1 << y
执行相同的1 << (y % 32)
事情,例如1 << -31 == 1 << 2 == 4
时Math.Pow(2, y)
会返回微小的2**y
分数(示例中为9.31322574615479E-10
)最后,相当于1 << y
// y >= 0
int result = unchecked((int) (Math.Pow(2, y % 32) + 0.5));
希望,这个公式能说明问题。这就是为什么请不要使用Math.Pow
代替转移