java - 优雅地删除浮动剩余物

时间:2012-01-31 08:06:09

标签: java floating-point rounding

简而言之 - 我很难将浮球留下来  (即10.00000123而不是10)

我走了:

我需要生成具有恒定间隙的浮点列表,如下所示 (实际上它是一张地图,我需要审视对象坚果没关系)

列表A:0.25,0.5,0.75,1,...

清单B:0.01,0.02,0.03,0.04,......

每次我得到一个号码,然后把它绕到列表中的neerest单元格 假设我得到0.051来检索列表A中的一个单元格 - 我返回0.05 让我说我得到0.21来检索列表B中的一个单元格 - 我返回0.25。

所以我开始这样做

float a = Math.round(Value / step) * step;

但是我得到了很多时间0.2500001(浮动剩菜) 我需要一种聪明的方法来绕过它。

也许通过获取点后的位数再做一次

Math.round(Value / 100) * 100;?

有更聪明的方法吗? 我试过了这个

        final float factor = Math.round(1 / step);
        final float value = (float) Math.round(value * factor) / factor;

但我有时会有这样的清单

列表A:10,15,20,25,30,......

当我22岁的时候,我会回到20岁的牢房。 问题是当我得到10的差距时

Math.round(1 / baseAssetStep) 

返回0 - 我得到NaN

4 个答案:

答案 0 :(得分:6)

使用BigDecimal代替float


来自原始数据类型的Java Tutorials

  

float: [...]此数据类型绝不能用于精确值,例如货币。为此,您需要使用   而是java.math.BigDecimal课程。数字和字符串涵盖   Java平台提供的BigDecimal和其他有用的类。

答案 1 :(得分:1)

简而言之,“这些不是您正在寻找的数字。”

浮点表示为二进制小数,而一些可以在base-10(例如0.01)中轻松表示的数字不能用有限数量的二进制数字表示。这类似于1/3在基数3中很容易(它只是0.1),但在基数10(0.333 ......)中需要无数个数字。

如果你试图在基数10中用有限数量的数字表示1/3,你会得到一个近似值。类似地,如果您尝试用基数2中的有限位数表示1/10(这是floatdouble所做的),您将得到近似值,类似于1/100 。您认为代码中的0.01实际上是一个非常接近但不完全等于1/100的数字。

有很多关于浮点的资源以及与它们合作的困难。 http://floating-point-gui.de/是一个很好的起点。

答案 2 :(得分:1)

首先,我会使用doublelong,因为它们具有更多的准确性数字。如果你真的需要,请使用BigDecimal,但很难找到doublelong无法完成工作的真实情况。

double d = 10.00000123;
double r = Math.round(d * 10000) / 10000.0;

或使用具有定点精度的long。

long l = 100000; // the actual value * 10000

定点精度的常见用例是金钱。而不是使用double美元,而是使用long甚至int美分。

答案 3 :(得分:0)

你需要一个恒定的差距,所以也许尝试另一种解决方案。抓住你的差距吧,我们把它命名为G.画一个randow int - 让我们称之为R,(如果你知道列表中的最大数字,你可以正确地绘制它)。现在唯一要做的就是R * G,它会从你的列表中给你一个数字 - 当然有一定的精度,因为这是不可避免的使用浮点数 - 打印它只是使用格式。您也可以将它与BigDecimal结合使用;)