使用java在float值中丢失精度

给出下面的测试代码及其输出。 当我从数值获得浮点值时,精度会丢失。任何人都可以告诉我为什么会出现这种行为以及如何处理这个问题?

public static void main(String[] args) { try { java.lang.Number numberVal = 676543.21; float floatVal = numberVal.floatValue(); System.out.println("Number value : " + numberVal); System.out.println("float value : " + floatVal); System.out.println("Float.MAX_VALUE : " + Float.MAX_VALUE); System.out.println("Is floatVal > Float.MAX_VALUE ? " + ( floatVal > Float.MAX_VALUE)); }catch(Exception e) { e.printStackTrace(); } } 

输出:

  Number value : 676543.21 float value : 676543.2 Float.MAX_VALUE : 3.4028235E38 Is floatVal > Float.MAX_VALUE ? false 

还为什么浮点值小于Float.MAX_VALUE?

我爱这些。 但我会快速无痛地做到。

浮点数和小数(也称为浮点数)也不会精确地保存在内存中。 但我不想在这里进入浮动精度与精度问题,我只想指出一个链接 – http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

至于你的另一个问题,lemme就是这样说的,因为浮点数是用科学记数法存储的。

 floatVal = 6.765432E6 = 6.7 * 10^6 MAX_VALUE = 3.4E38 = 3.4 * 10^38 

MAX_VALUE比浮点数大32个数量级。 随意看看这里http://steve.hollasch.net/cgindex/coding/ieeefloat.html

几个月前我花了很多时间来比较和解决一些FP问题……

比较浮点数时尝试使用小三角洲。 也许这个链接可以帮助你http://introcs.cs.princeton.edu/java/91float/

float s通常最多可达6位有效数字。 您的电话号码是676543.21 ,它拥有8位有效数字。 您看到超过6位数的错误,并且您执行的计算越多,这些错误将很容易传播到更高位数。 如果你重视你的理智(或精确度),请使用double s。 浮标甚至不能准确计算超过1000万。

现在,您有2位有效数字,这表明您有可能想要代表货币 – 请勿 。 使用您自己的类,使用定点算法在内部表示值。

现在,对于Float.MAX_VAL ,它是3.4028235E38,意思是3.4028235 * 10 ^ 38,这比你的值大10 ^ 32倍。 注意那里的’E’? 这就是指数。

所有数据类型都有表示限制,因此存在限制的事实应该不足为奇。

float使用24位作为其“尾数”,其中包含所有有效数字。 这意味着它有大约7位精度(因为2 ^^ 24大约是1600万)

double使用53位的“尾数”,因此它可以精确地保持大约16位数。

3.4028235E38大于676543.2。 Float.MAX_VALUE是可以表示的最大浮点数。

像您键入的十进制文字默认为double类型,而不是float 。 java.lang.Number默认也使用双精度数。 如果你用java.lang.Number numberVal = 676543.21f;替换它java.lang.Number numberVal = 676543.21f; 我希望两者的精度损失水平相同。 或者,替换float floatVal = numberVal.floatValue(); with double doubleVal = numberVal.doubleValue(); 为了不失精度。

编辑,作为一个例子,尝试运行:

 Number num = 676543.21; System.out.println(num); //676543.21 System.out.println(num.doubleValue()); //676543.21 System.out.println(num.floatValue()); //676543.2 <= loses the precision 

看到类型精度的差异

Float.MAX_VALUE返回float可以容纳的最大值。 任何更高的将溢出。 如果仔细观察,你会在文字表示中看到“E”。 这是标准的索引forms,'E'表示“乘以10乘以E后的任何数字的幂”(或者在java-speak * pow(10,numberAfterE)中)