为什么在非整数值上使用模数会失去浮点精度?

我想知道为什么我在使用这段代码时会失去精度:

double x = 12.0456; // or float : same result System.out.println(x); // outputs 12.0456 obviously x %= 1; // should now be equal to 0.0456 right? System.out.println(x); // outputs 0.04560000000000031 or 0.045599937 when using float 

12.0456模1应该等于0.0456对吗? 但它显示了一个略有不同的值,为什么我一直在失去精度? 我的意思是代码应该精确地减去1,直到值小于1。

但是,我发现了一种获得正确值的方法:

 double x = 12.0456; System.out.println(x); x %= 1; System.out.println((float)x); //outputs 0.0456 exactly 

这种方式很完美,但你们有更好的解决方案吗?

我不关心我应该使用哪种浮点类型,我只是想找到一种干净的方法来获得正确的值! 我不喜欢将值转换为double然后转换为float。

浮点数和双精度是不精确的 – 它们具有有限的位数来表示值。

因为人类使用基数10,而计算机使用基数2,对我们来说看起来“简单”的数字不可能准确地表示为浮点数/双精度数,尤其是由于CPU执行它们的计算结果。