繁体   English   中英

漂浮大于或小于零

[英]Float greater or less than zero

我有以下代码,有时返回为真,有时不返回。

知道可能导致变化结果的是什么吗?

0.00字符串来自JSON对象。

(代码简化)

if(new Float("0.00")>0){
    // do something
}

编辑:

我所拥有的是一些浮点数,我想确定它是零,小于零还是大于零。 值可以是0.00,0.001或-0.001之类的值。 如何确定它们是正面还是负面?

编辑:

也许我应该澄清我如何获得价值观。 我可能完全是导致问题的其他因素,因为我读到了BigDecimal并试图使用它无济于事。

使用以下代码从JSON提要(具有此格式LT:0.000)中提取值:

price = new BigDecimal(stocksJSONArray.getJSONObject(i).getString("LT"));

然后,为了测试价格是大于还是小于零,我使用了以下条件语句:

if(price.compareTo(BigDecimal.ZERO)==1){
    // greater than zero
}
else if(price.compareTo(BigDecimal.ZERO)==-1){
    // less than zero
}

此代码循环使用从JSON提要读取的许多值。 从结果中,一些零price被处理为大于零,一些价格被处理为小于零。 我怀疑还有其他因素导致这个问题吗?

我还做了一个测试,看看问题是否与数据的准确性有关。 所以我这样做了:

DecimalFormat frmt = new DecimalFormat("0.000000000000000000000000");
String formatted = frmt.format(stock.change);

对于被识别为正面和负面的零点,它的跟踪值仍然是0.000000000000000000000000 ,而不是0.000000000000000000000001或类似的东西。

您的表达式将在Java中可靠地生成false结果。

但是,假设零是例如-1除以无穷大的结果。 在这种情况下,它将在内部表示为,粗略地说,-0.00。 在某些情况下,它仍将打印为零(没有减号),在其他情况下,它的行为与0.00不同。

通常可以将浮点数与整数进行比较 - 与整数相同 - 存在舍入误差的风险,但是通过添加或减去随机小值无助于该错误。 平等的比较是不同的。

我建议你仔细检查你的事实,并做更多关于浮点行为的阅读

编辑 :我正在大大简化以上回答原始问题。 要回答问题的编辑,我们需要更深入。

对于浮点数的任何操作 ,应该知道并考虑输入的精度准确度 ,以及所需的输出精度 有时候任务是可以解决的,有时则不是 - 输入的准确性可能不足以产生答案。

在您的情况下, 精度为32位,其中24位是尾数,8位是指数。 这意味着此数据类型可以安全地区分0.001和0.00100001,但不能从0.001000001区分,因为您可以很容易地看到:

 System.out.println((float)0.001 < (float)0.001000001);

(请注意,如果你没有通过强制转换强制进行单精度比较,你会得到不同的结果。在这种情况下,计算将以双精度完成,并且数字将被安全地区分 - 直到你将它们拉得更近。)

因此,精度由数据类型决定。 不那么准确。 输入精度通常比精确度更具挑战性,因为它与数据类型无关,除了精度永远不会比精度更好。

数学实数可以在关于特定浮点类型中的可表示性的四种可能情况下找到它们,并且那些对应于当它作为文字出现时以其可读十进制符号表示它接收的不同处理。

  • 它可能在二进制中准确表示。 例如,0或0.25。 然后它就像一个整数变量那样精确。
  • 或者它的大致可表示与该类型精度相对应的精度。 例如,1/3或0.1或0.001。 当所需的指数适合可用的指数位数时,但是当数字的二进制扩展比尾数长或完全无穷时,就会发生这种情况。
  • 或者它具有大致可表示的精确度。 这些是非正规 (次正规)数。 这不仅是不准确的,它上面的算术可能会减慢到爬行,这通常是记录正确的行为,甚至一个受人尊敬的Java编译器可能会因为看到这种类型的文字而出汗,但这是一个错误
  • 或者根本不适合,编译器会拒绝文字太大。

因此,在您的情况下,我们只有三个有效输入:0(准确),0.001(近似值)和-0.001(近似值),这使您的问题可以解决。 只需将您的数字与0字面进行比较 (顺便说一句,这是准确的), 您将始终获得预期的布尔值 (完全准确的输出)。

然而,这取决于您的输入直接来自文字。 如果你的输入是0.001,-0.001和(float)1000 * (float)0.001 - 1 ,这将是一个不同的问题,你必须得到答案,例如像这样:

if (-0.00001 < x && x < 0.00001) // then x is zero 

如果您允许任何输入,不仅仅是那三个魔术值,并且对输入的准确性没有任何线索,那么这就是不可能的任务。 即使文字起始为0.000000000...一些垃圾数字也会被Java编译器转换为完全中性的零,并且在此之后,任何数量的Java代码都无法从准确和美丽的方面告诉它0.00 ,或者如果您向下溢值添加减号会发生什么。 它是完全相同的,不准确的零,变量中的相同位模式,而不是3个不同的值。

浮点数不准确。 您需要指定误差范围,例如:

float result = new Float("0.00");
float expected = 0;
if (Math.abs(result - expected) < 0.00001)
...

您可以使用Math.signum()来检查该值是否等于,小于或大于零。

我的确有点不同。 我期待一个传感器显示读数为1.这就是我想出的。

double a = y1;
                if((a-0)<1){
                    a=(1-a)+a;
                }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM