大家好,我正在学习java编程,我想知道为什么选择 符号位传播是“>>”而不是“>>>”? 我会假设<<和>>应该具有相同的实现。 对不起,如果这听起来像个愚蠢的问题:)
提前致谢!
答案 0 :(得分:3)
它以这种方式工作的原因是因为C和C ++在左移前使用<<
而在Java之前使用>>
进行右移。这些语言具有有符号和无符号类型,对于有符号类型,符号位以右移的方式传播。
Java没有无符号类型,因此它们保留了C和C ++的行为,以免产生混乱并引起全世界开发人员的不懈愤怒。然后他们包括>>>
以提供右移位,将位值视为无符号。
答案 1 :(得分:1)
这个问题实际上是关于阅读James Gosling的想法:-)。但我的猜测是,<<
和>>
在数学上都有意义:<<
会导致数字乘以2(除非溢出),而>>
会导致数字为除以2 - 当你有符号传播时,无论数字是正数还是负数,这都有效。也许语言设计者认为这比传播0的运算符更常用于右移,当整数被视为位串而不是实际数时,这更有用。无论哪种方式都是“正确的”或“错误的”,如果Gosling在早上吃早餐时有不同的东西,他可能会以某种方式看待你的东西......
答案 2 :(得分:1)
让我们从您没有问过的问题开始: - )
问:为什么没有<<<
?
A1:因为<<
对>>
和>>>
执行适当的反向操作。
>> N
相当于除以2 N >>> N
相当于除以2 N << N
等同于 N 乘以签名和无符号整数A2:因为符号位在左端,所以当你向左移动时“延伸”它是没有意义的。 (旋转是有意义的,但Java没有任何“旋转”运算符。原因:C先例,某些指令集缺乏硬件支持,Java代码中很少需要轮换。)
问:为什么只有>>
和>>>
中的一个签署了扩展名
答:因为如果他们都做了(或者两者都没有)那么你就不需要两个操作员。
现在你的问题(我认为):
问:为什么他们选择>>
进行签名扩展而不是>>>
?
答:这真的无法回答。据我们所知,目前没有公开的可用同期原始Oak / Java语言设计决策的记录。充其量,我们必须依靠詹姆斯·高斯林的记忆......以及他愿意回答问题。 AFAIK,这个问题没有被问到。
但是我的猜想是因为(大部分)签署了Java整数类型,所以认为>>
运算符会被更频繁地使用。事后看来,我认为Gosling等人做得对。
但这不是关于复制C或C ++。在这些语言中,只有一个右移运算符(>>
),其对有符号整数的行为是实现定义!! 。 Java中的>>>
运算符旨在解决该问题;即删除C / C ++ >>
的可移植性问题。
(参考:C11语言规范草案的6.5.7部分。)
接下来你的评论:
我认为
<<
和>>
应该具有相同的实现。通过相同的实现,我的意思是相同的过程,但方向相反。
上面已经回答了这个问题。从有用的功能的角度来看,>>
和<<
执行对签名号码执行相同的处理,但方向不同;即除法与乘法。对于无符号数字<<<
以相同方式对应>>
?
为何与众不同?它基本上取决于2的补码和无符号二进制表示的数学。
请注意,您无法执行>>
或>>>
的数学反转。直觉上,这些运算符丢弃右端的位。丢弃后,这些位无法恢复。
问:那么他们为什么不让<<
(或假设<<<
)“延伸”右手位?
答:因为: