简体   繁体   English

飞镖双分精度

[英]Dart double division precision

What is the correct way to perform this operation?执行此操作的正确方法是什么?

399.9 / 100

What I would expect to see is我希望看到的是

3.999

but the result is但结果是

3.9989999999999997

The result you see is correct , it's just not what you want.你看到的结果是正确的,只是不是你想要的。

Doubles are not precise values.双打不是精确的值。 The double you get by writing 399.9 is actually the precise value.通过写入 399.9 得到的 double 实际上是精确值。

399.8999999999999772626324556767940521240234375 399.8999999999999772626324556767940521240234375

That's the closest available double to the exact value 399.9.这是最接近精确值 399.9 的可用双精度值。 Any other double is at least as far away from 399.9 as that.任何其他双精度值都至少与 399.9 相差那么远。

Then you divide by 100. Again, the result is not precise, but the closest double has the exact value然后除以 100。同样,结果并不精确,但最接近的双精度值具有精确值

3.99899999999999966604491419275291264057159423828125 3.99899999999999966604491419275291264057159423828125

That differs from what you would get by writing 3.999, which is the exact value:这与您通过编写 3.999 得到的不同,这是确切的值:

3.999000000000000110134124042815528810024261474609375 3.999000000000000110134124042815528810024261474609375

At every step, the double operations have minimized the error, but because you are doing multiple steps, the final result diverges from the double closest to the mathematical result.在每一步,double 运算都将误差最小化,但是由于您执行了多个步骤,因此最终结果与最接近数学结果的 double 有所不同。

What you need to do depends on what your actual requirements are.您需要做什么取决于您的实际需求。

If you want to always calculate with two significant digits, then I'd just multiply my numbers with 100 and do all the operations as integer operations, until the very last division by 100.如果您想始终使用两位有效数字进行计算,那么我只需将我的数字乘以 100 并将所有运算作为整数运算进行,直到最后除以 100。

If you have an intermediate result and wants to round it to two digits, I'd do what Fy Z1K says:如果您有一个中间结果并希望将其四舍五入为两位数,我会按照 Fy Z1K 所说的进行操作:

  result = (result * 100).round() / 100;
import 'dart:math';

double roundDouble(double value, int places){ 
    double mod = pow(10.0, places); 
    return ((value * mod).round().toDouble() / mod); 
}

then you would basically get那么你基本上会得到

double num1 = roundDouble(12.3412, 2);
// 12.34

double num2 = roundDouble(12.5668, 2);
// 12.57

double num3 = roundDouble(-12.3412, 2);
// -12.34

double num4 = roundDouble(-12.3456, 2);
// -12.35

To make decimal operations you can use the decimal package .要进行十进制运算,您可以使用小数包

final d = Decimal.parse;
print(d('399.9') / d('100')); // => 3.999

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

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