[英]What is the difference between “1 << x” and “pow(2, x)”?
因此,在使用Unity时,我不得不使用按位运算符。 现在,请不要误会我,我完全了解按位运算符的用处,并且在某些情况下,如果不编写一堆难看的代码,就无法替换它。 问题更像是……a和b之间有什么区别,在这里:
double a = 1 << 3;
double b = Math.Pow(2, 3);
根据我对函数和二进制的理解,在两种情况下,最后一个位置都是1,等于8。是什么阻止任何人在按位运算符上使用Math.pow? 它真的会改变某些东西吗?
一般而言,对于大多数语言:
pow函数的效率可能较低,因为它实际上是通用的,并且可以将任何数量的幂提高为任何幂,因此在特殊情况下无法轻松地进行优化。
移位将直接映射到处理器级别的操作。
在某些语言中,编译器会看到这些运算具有恒定的结果并使用该结果,但是,如果复杂度稍高,则可能会忽略优化。
是什么阻止任何人通过按位运算符使用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)
Math.Pow(2, y)
要进行FPU计算时Math.Pow(2, y)
1 << 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
而不是shift
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.