繁体   English   中英

“ 1 << x”和“ pow(2,x)”有什么区别?

[英]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? 它真的会改变某些东西吗?

几件事:

  1. (int) Math.Pow(2, y); 可读性低于1 << y
  2. (int) Math.Pow(2, y)可能会带来讨厌的错误,例如2.0**10.0似乎是1023.99999997 我们必须添加更加繁琐的(int) (Math.Pow(2, y) + 0.5)
  3. Math.Pow(2, y)要进行FPU计算时Math.Pow(2, y) 1 << y快得多(大约一个CPU滴答)。
  4. 1 << 31-2147483648 ,这在按位逻辑中很方便。 (int)Math.Pow(1, y)情况下,您可以抛出OverflowException
  5. 1 << y == 1 << (y % 32) ,因此例如1 << 40 == 1 << 8 == 256 ,这也很方便。
  6. 如果y 1 << y做相同的1 << (y % 32) ,例如1 << -31 == 1 << 2 == 4Math.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM