我正在尝试编写一个获取double
的方法,验证该数字是否在点之后有什么内容,如果确实有 - 返回double
,如果没有则返回{ {1}}。
int
输出:
public class Solution {
public static void main(String[] args) {
double d = 3.000000000;
System.out.println(convert1(d));
System.out.println(convert2(d));
}
static Object convert1(double d) {
if(d % 1 == 0)
return (int) d;
else
return d;
}
static Object convert2(double d) {
return ((d%1) == 0) ? ((int) (d)) : d;
}
}
因此,我想要的一切都发生在方法3
3.0
中,但不会发生在方法convert1()
中。看来这些方法必须做同样的工作。但我做错了什么?
答案 0 :(得分:25)
您会看到与the one in this question类似的效果。
使用三元运算符处理Java的方式与使用if
语句处理类型的方式略有不同。
具体来说,standard says:
条件表达式的类型确定如下:
...
否则,如果第二个和第三个操作数具有类型 convertible(§5.1.8)到数字类型,然后有几种情况:
...
否则,二进制数字促销(第5.6.2节)将应用于 操作数类型和条件表达式的类型是 提升了第二和第三个操作数的类型。
翻到标准页面we see:
如果任一操作数的类型为double,则另一个操作数转换为double。
这是在这里发生的事情,然后自动装箱到Double
。似乎if
语句没有发生这种转换,解释了差异。
更广泛地说 - 这不是一个好主意。根据价值,我不认为退回int
或double
中的一个是好的设计 - 如果你要关闭某些东西,请使用Math.floor
,如果你不赞成不希望打印小数,请使用printf
。
编辑:我认为做一些hacky事情来规避常规数字转换系统并不是一个好主意。这是一个直接为您提供String
的想法,这似乎是您想要的:
static String convert3(double d) {
return ((d % 1 == 0) ? Integer.toString((int)d) : Double.toString(d));
}
答案 1 :(得分:15)
正如其他答案所述,这种行为是因为三元表达式的两种可能结果必须具有相同的类型。
因此,为了使您的三元版本与convert1()
的工作方式相同,您需要做的就是将int
投射到Object
:
static Object convert2(double d) {
return ((d % 1) == 0) ? ((Object) (int) (d)) : d;
}
答案 2 :(得分:11)
三元运算符要求两个结果值都是相同的类型,因此int
会自动(安全)扩展到double
。
三元与if
“等价物”不完全相同。
答案 3 :(得分:0)
解决点后的数字问题:
public Object convert(double number){
double whole = Math.floor(number);
if(Math.abs(whole - number) < DELTA){
return (int) number;
}
return number;
}
DELTA
是足够小的常量,用于解决浮点格式编码的整数问题。
我已经从内存中编写了代码,但我认为其背后的想法很明确。