Java - 如何减少浮点数精度?

时间:2017-02-27 15:25:37

标签: java

我可以降低浮点数的精度吗?  在我一直在做的所有搜索中,我只看到了如何降低打印数字的精度。我不需要打印它。  例如,我希望将13.2836转换为13.28。甚至没有四舍五入。

有可能吗?

系统建议的答案不是我要找的。它还涉及打印价值,我希望有一个浮动。

感谢。

4 个答案:

答案 0 :(得分:2)

虽然john16384的答案暗示了这一点,但他的回答并没有解决问题......所以你可能会尝试它,它不会做你想做的事,也许你仍然不知道为什么......

问题在于,虽然我们用十进制思考并期望小数点由10的幂指数控制,但典型的浮点实现(包括Java float)使用2次幂指数。为什么重要?

你知道要用十进制表示1/3,你说0.3(重复) - 所以如果你的十进制数字有限,你就不能 代表代表1/3。当指数为2而不是10时,你不能 代表1/5,或者你可以完全代表十进制的许多其他数字。

碰巧.28是其中一个数字。因此,您可以乘以100,将结果传递给floor,然后除以100,但是当它转换回float时,结果值将与.28略有不同,因此,如果你检查它的值,你仍然会看到超过2位小数。

解决方案将使用类似BigDecimal的内容,它可以精确地表示给定精度的十进制值。

答案 1 :(得分:1)

如果您需要在计算的某些部分保存内存,并且您的数字小于float number = 1.2345667f; number= (short)(100*number); number=(float)(number/100); (范围简短),则可以执行以下操作。 部分内容来自这篇文章https://stackoverflow.com/a/25201407/7256243

short

您只需要记住{{1}}的尺寸要大100倍。

答案 2 :(得分:0)

关于使用浮点数进行精确算术的标准警告适用,但您可以这样做:

float f = 13.2836;

f = Math.floor(f * 100) / 100;

答案 3 :(得分:0)

大多数答案直接传到how do represent floats more accurately,这很奇怪,因为你问:

  

我可以降低浮点数的精度

恰恰相反。所以我会试着回答这个问题。

然而,有几种方法可以“降低精确度”:

  • 降低精度以获得性能
  • 减少内存占用
  • 任意圆/地板
  • 使号码更“模糊”
  • 减少昏迷后的位数

我将分别解决这些问题。

降低精度以获得性能

只是为了让它脱离困境:仅仅因为你在浮动上降低计算精度,并不意味着它会更快。恰恰相反。这个答案来自@ john16384:

f = Math.floor(f * 100) / 100;

只会增加计算时间。如果您知道结果中有效数字的数量很少,请不要删除它们,只需携带带有数字的 信息:

public class Number WithSignificantDigits {
    private float value;
    private int significantdigits;

    (implement basic operations here, but don't floor/round anywhere)
}

如果你这样做是因为你担心性能:现在停止它,只需使用全精度。如果没有,请继续阅读。

减少内存占用

要实际存储一个精度较低的数字,您需要远离float

一个这样的表示是使用具有固定点约定的int(即最后2位数经过昏迷)。

如果您尝试节省存储空间,请执行此操作。如果没有,请继续阅读。

任意圆/地板

为了继续使用float,但是降低其精度,存在几个选项:

@ john16384建议:

`f = Math.floor(f * 100) / 100;`

甚至

f = ((int) (f*100)) / 100.;

如果答案是这样,那么您的问题就是重复。如果没有,请继续阅读。

使数字更“模糊”

既然你只是想要失去精确度,但是没有说明多少,你可以做按位移动:

float v = 0;
int bits = Float.floatToIntBits(v);
bits = bits >> 7; // Precision lost here
float truncated = Float.intBitsToFloat(bits);

使用7位移位将精度降低到最接近的1/128(接近1/100) 使用10位移位将精度降低到最接近的1/1024(足够接近1/1000)

我没有测试过那些表现,但如果你读了这篇,你就不在乎了。

如果你想要失去精确度,而你不关心格式化(数字可能在昏迷后有大量的数字,比如0,9765625而不是1),这样做。如果您关心格式化并且在昏迷后想要有限数量的数字,请继续阅读。

减少昏迷后的位数

为此你可以:

  • 关注@Mark Adelsberger对BigDecimals
  • 的建议
  • String yuk
  • 的身份存储

由于floatdouble s在大多数情况下都不允许这样做。