我希望获得一天中的微秒数
所以我按照以下方式尝试了
long microDay = 24 * 60 * 60 * 1000 * 1000;
我希望它的值为86400000000
,但是当我打印它时
System.out.println(microDay);
值为500654080
花了3个小时后我才知道原因,最后我发现java认为24,60和1000为int值而int*int =int
但是int的最大值是2147483647所以它不能存储86400000000和因此它的输出是500654080(但我不确定)
在第二种情况下,我想计算一天内的毫秒数,公式就像这样
long miliDay = 24 * 60 * 60 * 1000;
System.out.println(miliDay );
输出 86400000
现在我做的时候
System.out.println(microDay/ miliDay);
输出 5
但是当我在计算器500654080/86400000= 5.794607407407407
中尝试此操作时
为什么会有不同的结果?
答案 0 :(得分:3)
您正在执行32位整数运算,因为24 * 60 * 60 * 1000 * 1000
中的每个操作数都是int
...但结果大于Integer.MAX_VALUE
,所以它&#39 s溢出(就像你怀疑的那样)。 (在这种情况下,这实际上是在编译时发生的,因为它是一个编译时常量,但效果与在执行时发生的效果相同。)
实际上,每个操作都被截断为32位。碰巧的是,只有最终乘以1000会使结果超过2 31 - 86400000就可以了。
二进制中的86400000000是:
1010000011101110101110110000000000000
^
\- Bit 33
因此,在溢出之后,我们只需切断任何前导位,直到我们得到32:
00011101110101110110000000000000
该值为500654080。
只需使用long
,例如
long microDay = 24L * 60L * 60L * 1000L * 1000L;
(你绝对不需要所有这些常量属于long
类型,但保持一致意味着很明显所有操作都将使用64位算术,无需考虑关联性等。)
然而,更好的方法是使用TimeUnit
:
long microDay = TimeUnit.DAYS.toMicroseconds(1);
对于除法部分,您执行整数除法 - 因此结果是整数部分,舍入为0.如果要进行浮点运算,则需要将其中一个操作数转换为{{1} }或float
...虽然如果你从正确的值开始,当然,你应该得到一个精确的整数(1000)。
答案 1 :(得分:2)
对于第一部分,放一个" L"在一个(或多个)常量的末尾,Java将使用长算术。 e.g。
long microDay = 24L * 60 * 60 * 1000 * 1000;
附录:你为什么得到500654080?
86400000000十进制= 141DD76000十六进制。 但是,整数只保存32位,即8"数字"。所以你失去领先的14并保留1DD76000十六进制。 将其转换为十进制给出500654080。
至于除法,当你用整数划分整数(或长整数)时,Java会将结果作为int或long返回,因此它必须截断(或舍入,但Java选择截断)结果为5 5.7946 ...强制它通过将其中一个值转换为double来执行浮点运算,例如
System.out.println((double)microDay/ miliDay);
答案 2 :(得分:0)
当您在2个整数之间执行除法时,结果是整数。算术运算的结果将向下舍入到最接近的整数。
int i = 5 / 2; // 2.5 is rounded down to 2
如果希望输出包含小数精度,则需要使用不同的基本数据类型,并明确指定操作数为双精度。
double j = 5 / 2; //2.0 as 5 / 2 yields and integer 2 which will be casted to a double
double j = 5 / 2.0; //2.5 explicit usage of a double will tell the compiler to return the results in double
答案 3 :(得分:0)
内部的核行动
long microDay = 24 * 60 * 60 * 1000 * 1000;
都是特定的整数。 Integer对象的最大值为2147483647.这超出了原始输出的长度。
简单地指定long to variable并不意味着使用[*]的所有操作都将使用long实例完成。在任务中完成的所有操作都被截断了。
解决方案是明确指定所有核操作都应该在长实例上发生,而不是在int实例中发生。
long microDay = 24L * 60L * 60L * 1000L * 1000L;