我不明白为什么这个 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/Floatdouble/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