我不明白为什么这个 Java 问题中变量 result 的值是非零的
I do not understand why the value of the variable result is nonzero in this Java question
我有这个问题:
您认为执行以下 Java 代码段后变量 result 的值是多少?
int i = 1234567890;
float f = i;
int result = i - (int)f;
The answer is nonzero
请记住,我是 java 的初学者,目前正在学习绝对基础知识,坦率地说,我不明白为什么答案是非零的,以及代码的每一行实际上意味着什么?
tl;博士
如果您想要小数的准确性,请使用 BigDecimal
class 而不是 float
浮点类型。
浮点数不准确
float
/Float
和 double
/Double
trade away accuracy 使用浮点技术提高执行速度。切勿在准确性很重要的地方使用这些类型,例如金钱。
因此将整数转换为浮点数并再次转换回来可能不会产生相同的数字。
此行为并非 Java 所特有。 Java 实现了 electrical engineering standards defining floating-point arithmetic 行为。任何支持标准浮点数的编程语言都会出现同样的问题。
int i = 1234567890; // Create an integer number from literal input, and store as a primitive value in variable named `i`.
float f = i ; // Convert the integer `int` primitive to a fractional number represented using floating-point technology as a primitive value in variable named `f`.
int backAgain = (int)f ; // Cast (convert) from a `float` type to a `int` type. Data-loss may be involved, as any fraction is truncated.
int result = i - backAgain ; // Subtract one `int` primitive from the other `int` primitive. Store the integer result in a primitive `int` variable.
boolean isZero = ( result == 0 ) ; // Test if the result of our subtraction is zero.
看到这个code run live at IdeOne.com。
i: 1234567890
f: 1.23456794E9
backAgain: 1234567936
result: -46
isZero: false
BigDecimal
如果在处理小数时想要准确性而不是速度,请使用 BigDecimal
class。
int i = 1234567890;
BigDecimal bd = new BigDecimal( i ) ;
int backAgain = bd.intValueExact() ;
int result = i - backAgain ;
boolean isZero = ( result == 0 ) ;
看到这个code run live at IdeOne.com。
isZero: true
i: 1234567890
bd: 1234567890
backAgain: 1234567890
result: 0
isZero: true
我有这个问题:
您认为执行以下 Java 代码段后变量 result 的值是多少?
int i = 1234567890;
float f = i;
int result = i - (int)f;
The answer is nonzero
请记住,我是 java 的初学者,目前正在学习绝对基础知识,坦率地说,我不明白为什么答案是非零的,以及代码的每一行实际上意味着什么?
tl;博士
如果您想要小数的准确性,请使用 BigDecimal
class 而不是 float
浮点类型。
浮点数不准确
float
/Float
和 double
/Double
trade away accuracy 使用浮点技术提高执行速度。切勿在准确性很重要的地方使用这些类型,例如金钱。
因此将整数转换为浮点数并再次转换回来可能不会产生相同的数字。
此行为并非 Java 所特有。 Java 实现了 electrical engineering standards defining floating-point arithmetic 行为。任何支持标准浮点数的编程语言都会出现同样的问题。
int i = 1234567890; // Create an integer number from literal input, and store as a primitive value in variable named `i`.
float f = i ; // Convert the integer `int` primitive to a fractional number represented using floating-point technology as a primitive value in variable named `f`.
int backAgain = (int)f ; // Cast (convert) from a `float` type to a `int` type. Data-loss may be involved, as any fraction is truncated.
int result = i - backAgain ; // Subtract one `int` primitive from the other `int` primitive. Store the integer result in a primitive `int` variable.
boolean isZero = ( result == 0 ) ; // Test if the result of our subtraction is zero.
看到这个code run live at IdeOne.com。
i: 1234567890
f: 1.23456794E9
backAgain: 1234567936
result: -46
isZero: false
BigDecimal
如果在处理小数时想要准确性而不是速度,请使用 BigDecimal
class。
int i = 1234567890;
BigDecimal bd = new BigDecimal( i ) ;
int backAgain = bd.intValueExact() ;
int result = i - backAgain ;
boolean isZero = ( result == 0 ) ;
看到这个code run live at IdeOne.com。
isZero: true
i: 1234567890
bd: 1234567890
backAgain: 1234567890
result: 0
isZero: true