我有以下代码:
public static final long KILOMETER_IN_METERS = 1000;
public static int getKilometers(int distanceInMeter) {
return (int) Math.floor(distanceInMeter / KILOMETER_IN_METERS);
}
对于带有 return 语句的行,Sonar说:
Integral division result cast to double or float
Here is the full description of this bug.
据我所知,它表示有 int / int 除法,其结果可能是浮动值,但我可能错了。
我该如何正确处理这个案子?
答案 0 :(得分:2)
此处无需使用Math.floor
。 Math.floor
是double
上的一个操作,当你向它提供一个int时它什么都不做。
返回最大(最接近正无穷大)
double
小于或等于参数的值 并且等于数学整数。特殊情况:
- 如果 那么,参数值已经等于一个数学整数 结果与参数相同。
- 如果参数是 NaN或无穷大或正零或负零,然后是 结果与参数相同。
(Source)
整数除法已经具有Math.floor
的相同逻辑行为,即它截断除法运算的其余部分。 int/int
始终返回int
。
例如,100/3
将返回33
,40/50
将返回0
。
只需使用此代码:
public static int getKilometers(int distanceInMeter) {
return distanceInMeter / KILOMETER_IN_METERS;
}
答案 1 :(得分:2)
那是因为Math.floor
将double作为参数,整数除以整数已经是整数。因此,所有的铸造声纳呜呜声都在那里完成,而不是你明确的演员int
。
以下是floor
的文档:http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#floor%28double%29
答案 2 :(得分:2)
要扩展Eran的回答,请点击以下内容:
distanceInMeter / KILOMETER_IN_METERS
将整数除以整数。在Java中,该结果是截断的整数。然后你将它放入Math.floor
,这需要一倍。因此,Java会将int
变为double
,从而帮助您解决问题。然后,您将double
返回的Math.floor
转发回int
。
如果你一直在跟踪,你可能已经注意到你已经截断了int。所以你的代码需要简单:
public static int getKilometers(int distanceInMeter) {
return distanceInMeter / KILOMETER_IN_METERS;
}
答案 3 :(得分:2)
当你除去两个整数时,你将总是得到一个整数,向下舍入。
如果您除以distanceInMeter / KILOMETER_IN_METERS
然后将其指定为双精度数,则在分配之前首先将其划分为int
eger,这样您就会得到一个向下舍入的值,转换为double
。
Sonar没有因为Math.floor
而抱怨 - 它抱怨因为你将整数除法结果(它本身是一个向下的int
eger)转换为double
。大多数情况下,这是一个错误(为什么故意自动舍入并立即转为双倍)?
int distanceInMeter = 505;
double result = distanceInMeter / KILOMETER_IN_METERS;
System.out.println(result); // 0.0
double result2 = distanceInMeter * 1.0 / KILOMETER_IN_METERS;
System.out.println(result2); // 0.505
double result3 = ((double) distanceInMeter) / KILOMETER_IN_METERS;
System.out.println(result3); // 0.505
1.0 * distanceInMeter / KILOMETER_IN_METERS
((double)distanceInMeter) / KILOMETER_IN_METERS