繁体   English   中英

Java浮点精度问题

[英]Java Floating Point Precision Issue

我有一个关于java中浮点运算及其精度的问题。 我确实在这里和通过谷歌进行了研究并遇到了一些解决方案,但在我的设计中实施它们时遇到了困难。 所以在Java中我正在使用BigDecimal类来使我的计算准确。 请注意,变量是double,并且在进行计算时,值的精度最多可达到右侧的8位小数。 显示的结果(精度)是已知的,这就是我将要存储的当前值。 此外,所有值都是动态的(通过方法)。 传递的参数应该是currentValue +步长。

public void newValue(float value) {

  //Clip to valid range, can't go over minimum/max value
  value = Math.max(minimumValue, Math.min(maximumValue, value));

  // TODO Implement better Floating Point Arithmetic precision

  MathContext mcI = new MathContext(0, RoundingMode.HALF_UP);      
  MathContext mcF = new MathContext(8, RoundingMode.HALF_UP);
  BigDecimal valueBD = new BigDecimal(value, mcF);
  BigDecimal minimumBD = new BigDecimal(minimumValue, mcF);
  BigDecimal stepBD = new BigDecimal(step, mcF);
  BigDecimal currentValueBD = new BigDecimal(currentValue, mcF);


  BigDecimal totalStepsBD = valueBD.subtract(minimumBD, mcF);

  //Ensure value is divisible by stepsize
  totalStepsBD = totalStepsBD.divide(stepBD, mcI);

  valueBD = stepBD.multiply(totalStepsBD, mcF);

  valueBD = valueBD.add(minimumBD, mcF);

  // arithmetic without using BigDecimal (old)
  //int totalSteps = (int) ((value- minimumValue)/ step);
  //value = totalSteps * step + minimumValue;

  if(!(valueBD.equals(currentValueBD))) {
     valueBD = valueBD.setScale(displayPrecision, RoundingMode.HALF_UP);
     currentValue = valueBD.floatValue();
     dispatch();
  }

}

现在,它适用于某些值但不是全部。 特别是当我搞乱步长时。 所以,如果步数= 0.1,那很好。 如果我把它设为0.005,我会得到一个AirthmeticException - 非终止十进制扩展的步骤

totalStepsBD = totalStepsBD.divide(stepBD, mcI);

当为步骤变量设置.005时,在制作BigDeciaml(stepBD)之后它会出现.0049999999 ...不确定是否有帮助,但如果您有任何想法,请告诉我。 谢谢。

String step (和String value )传递给BigDecimal构造函数。 你不能精确地将0.005表示为double (或float )。

 BigDecimal stepBD = new BigDecimal("0.005"); // <-- works as a `String`.

编辑

或者如下所述,使用BigDecimal.valueOf(double)

 BigDecimal stepBD = BigDecimal.valueOf(0.005);

暂无
暂无

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

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