任何人都可以确认这是否属实?
Java会将long
%int
转换为long
值。但是,它永远不能大于模数,将其强制转换为int
。
long a =
int b =
int c = (int) (a % b); // cast is always safe.
同样,long
%short
始终可以安全地投放到short
。
如果是,那么是否有人知道为什么Java %
的类型比需要更长?
此外,long
& int
(如果您忽略符号扩展名)
答案 0 :(得分:14)
对于大多数(如果不是全部)算术运算,Java将假定您需要最大定义的精度。想象一下,如果你这样做:
long a = ...;
int b = ...;
long c = a % b + Integer.MAX_VALUE;
如果Java自动将a % b
下载到int
,则上述代码会导致int
溢出,而不是将c
设置为完全合理{{1}价值。
这与使用long
和double
执行操作会产生int
的原因相同。将最不准确的值向上投射到更准确的值更安全。然后,如果程序员比编译器知道更多并且想要向下转换,他可以明确地做到。
答案 1 :(得分:10)
总是安全的! (数学与我同意。)
mod操作的结果总是小于除数。由于mod运算的结果基本上是执行整数除法后的余数,因此永远不会有大于除数的余数。
我怀疑让操作返回long
的原因是因为除数在操作发生之前扩展到long
。这样可以获得long
结果。 ( note 即使变量在内存中展开,其值也不会发生变化。展开的int
永远不会大于int
可以容纳的变量。)
答案 2 :(得分:4)
正如Marc B所提到的,Java会在实际进行b
操作之前将long
提升为%
。此促销适用于所有算术运算,我相信<<
和>>
。
换句话说,如果您有二进制操作且两个参数的类型不同,则会提升较小的一个,以便双方具有相同的类型。
答案 3 :(得分:3)
这是一个迟到的派对,但原因很简单:
字节码操作数确实需要显式转换(L2I
),long需要2个堆栈位置,而int,char,short,byte则为1 [从byte转换为int不需要字节码指令]。在mod操作之后,结果在堆栈顶部占据2个位置。
编辑:另外,我忘了提到Java没有64b / 32b的除法/余数。只有64-> 64位操作,即LDIV
和LREM
。
答案 4 :(得分:1)
有没有人知道为什么Java的类型比%需要更长?
我不确定。也许是为了使其工作方式与其他乘法运算符完全相同:*
和\
。在JLS The type of a multiplicative expression is the promoted type of its operands.
中添加long % int
的例外会让人感到困惑。