整数乘法(暂时忘记分裂)之间的差异是否仍然有利于转移?如果是这样,差异有多大?
它似乎只是一个低级别的优化,即使你想要它不应该是(C#/ Java)字节码编译器或jit在大多数情况下捕获它?
注意:我测试了C#的编译输出(使用gmcs Mono C#编译器版本2.6.7.0),即使乘以2的倍数,乘法示例也不使用shift进行乘法。
C# http://csharp.pastebin.com/hcrRnPrb
CIL http://csharp.pastebin.com/0js9F2c1
P.S。 我忘了在字节上使用它有多大帮助,但在使用它时仍然遇到一些麻烦。
答案 0 :(得分:22)
第一个原因:
有时 - 大多数情况下 - 您希望将整数视为数字。有时虽然整数是表示一组位的便捷方式。
乘法是对数字的操作。
移位是对一组位的操作。
在乘法结果和移位结果之间恰好存在关系并不是特别相关。这些操作逻辑上不同。
第二个原因:
C#和Java都是为C开发人员所熟悉的,尽管是肤浅的。因此,来自C的常用习语包含在C#和Java中。
答案 1 :(得分:12)
如果我想将数字乘以4,我会写* 4
。如果我的目的是左移一些位2位,我会写<< 2
。
回答问题:
为什么Java和C#有位移操作符?
我在二进制数据上做了很多工作,其中我没有考虑整数等 - 只是二进制 - 并且在那个区域中完全逻辑使用不断转移运营商。
当然,我可以输入* 2
等,但我真正想要做的事情就是移位。
这在字节很重要的一系列领域很常见(例如图形编程,序列化等)。
此外,还有一些微妙的移位操作,其中不希望它表现得像一个整数,特别是在处理边缘时......当你从地图左移一点,或者将右移到地图(-ve vs + ve等)时发生的事情的规则很好理解但很关键。同样,整数乘法的checked
/ unckecked
行为有时非常重要。
答案 2 :(得分:8)
你是对的,如果移位运算符仅用作乘法的替代,它应该留给编译器。
我想你忽略了以下应用程序:
还有更多需要在没有本机代码的情况下进行高效实现。
答案 3 :(得分:1)
你所问的基本上不是C#/ Java中存在bithift运算符的原因,而是为什么javac
编译器不会将乘法和除法与2的幂优化为位移。
对此的下意识反应是乘法和除法具有与位移不同的语义,因此它不会映射100%来替换操作。
此外,您忘记了JIT(HotSpot)中发生的额外编译步骤,其中发生了各种其他优化。坦率地说,没有必要优化这个特定的步骤,而不是C代码就像编译器生成它一样。
答案 4 :(得分:0)
因为语言设计师认为拥有它们会很好。
它们与其他一些操作相当并不重要,并且编译器足够聪明以有效地实现操作。如果那就是我们要去的地方,那么除了宏汇编程序和非常好的链接时优化器之外,你可能需要的不仅仅是带有垃圾收集器的虚拟机。这些不是语言设计师通常追求的目标。
答案 5 :(得分:0)
例如,您的程序可能会使用像位掩码之类的东西。在那种情况下,位移操作是必要的。或者,如果您只是在解决一些需要以指定方式编码状态的奇怪任务。
观看此tutorial - 大多数样本来自数学问题。如果你只是制作一个网站或一个GUI应用程序,你可能不需要转移,但有时你真的这样做......
答案 6 :(得分:0)
这样你就可以左右移位。你希望那些位和它们的移位操作代表什么完全取决于你。
答案 7 :(得分:0)
除了其他原因之外,还有很多情况下您可能需要转移(或其他位操作)以通过网络与第三方库或远程应用程序进行交互。