Java 失去了精确性。我该怎么处理?

Java 失去了精确性。我该怎么处理?,java,math,precision,Java,Math,Precision,我正在模拟一个系统,它包含0到1之间的特定能量。这存储在名为storedEnergy的双精度存储库中 storedEnergy应在21分钟内从0.0计数到1.0,但应计数到1.0000000000000004 每次迭代storedEnergy都会在storedEnergy-increasePerminute上增加 onSlackMinutesIncreasePerMinute = (double) time1to0Energy / (double) time0to1Energy; onS

我正在模拟一个系统,它包含0到1之间的特定能量。这存储在名为
storedEnergy
的双精度存储库中

storedEnergy
应在21分钟内从0.0计数到1.0,但应计数到1.0000000000000004

每次迭代
storedEnergy
都会在storedEnergy-increasePerminute上增加

  onSlackMinutesIncreasePerMinute = (double) time1to0Energy / (double) time0to1Energy;
  onStoredEnergyIncreasePerMinute = 1d / (double) time0to1Energy;
  offSlackMinutesDecreasePerMinute = 1d;
  offStoredEnergyDecreasePerMinute = 1d / (double) time1to0Energy;
以下是储能的增加:

  while (storedEnergy < target) {
     storedEnergy += onStoredEnergyIncreasePerMinute;
  } 
while(storedEnergy
类似的情况也发生在空闲分钟上:能量为1.0时有24.999999993,而能量为1.0时应该有25

可能需要提到的是,我将使用
offstoredenergyderenceperminute
倒计时到0,持续25分钟

我不知道为什么会发生这种情况(尽管我认为这与双倍不能正确表示分数有关),或者我应该怎么解决它。我必须使用某种分数类吗

我想这与双打不能正确地表示分数有关

没错,浮点数只能精确地表示二进制分数,并且精度达到一定的极限

你应该仔细考虑你的计算使用的一组数字。如果它只是有理数,那么你可以相对简单地用两个整数实现它。如果采用平方根或类似的方法,则没有精确的数值表示

我想这与双打不能正确地表示分数有关

没错,浮点数只能精确地表示二进制分数,并且精度达到一定的极限


你应该仔细考虑你的计算使用的一组数字。如果它只是有理数,那么你可以相对简单地用两个整数实现它。如果您采用平方根或类似值,则没有精确的数字表示。

看起来您在此处过度添加了:

 while (storedEnergy < target) {
     //this goes above 1.0 on the final iteration
     storedEnergy += onStoredEnergyIncreasePerMinute;  
  } 
while(storedEnergy
您可以通过执行以下操作进行修复:

 while (storedEnergy < target) {
     storedEnergy += onStoredEnergyIncreasePerMinute;
     if(storedEnergy>target)
        storedEnergy = target;

  } 
while(storedEnergy目标)
storedEnergy=目标;
} 

看起来像是您在此处过度添加:

 while (storedEnergy < target) {
     //this goes above 1.0 on the final iteration
     storedEnergy += onStoredEnergyIncreasePerMinute;  
  } 
while(storedEnergy
您可以通过执行以下操作进行修复:

 while (storedEnergy < target) {
     storedEnergy += onStoredEnergyIncreasePerMinute;
     if(storedEnergy>target)
        storedEnergy = target;

  } 
while(storedEnergy目标)
storedEnergy=目标;
} 

阅读以了解发生这些错误的原因。尝试设置您希望变量具有的精度或使用舍入函数,以绕过表示问题,了解这些错误发生的原因。尝试设置您希望变量具有的精度或使用舍入函数,以绕过表示问题

它确实与浮点、双精度和所有浮点数字表示有关。。。由于这些数字保存为有效、基数和指数,因此无法准确显示某些数字。我建议使用round()ceil()和floor()等round函数,但由于这更像是一种修复或解决方法,而不是一种解决方案,因此我不会将其作为答案发布。除非使用舍入,否则不要在迭代中使用double。另外,除非使用舍入,否则不要使用浮点或小数。Java是否有可以使用的不限精度的有理数数据类型?在Python领域,我们有
分数
。也许这会有所帮助:浮点数不是无限精确的。看,它确实与浮点数、双精度和所有浮点数表示有关。。。由于这些数字保存为有效、基数和指数,因此无法准确显示某些数字。我建议使用round()ceil()和floor()等round函数,但由于这更像是一种修复或解决方法,而不是一种解决方案,因此我不会将其作为答案发布。除非使用舍入,否则不要在迭代中使用double。另外,除非使用舍入,否则不要使用浮点或小数。Java是否有可以使用的不限精度的有理数数据类型?在Python领域,我们有
分数
。也许这会有所帮助:浮点数不是无限精确的。见+1。这确实假设舍入
storedEnergy
不会影响程序的运行方式,但如果是这样,则double不是正确的开始类型。+1。这确实假设舍入
storedEnergy
不会影响程序的运行方式,但如果是这样,则double不是正确的开始类型。