给定一个double,我希望将它四舍五入到小数点后的给定精度点数,类似于PHP的round()函数。
我能在Dart文档中找到的最接近的东西是double.toStringAsPrecision(),但这不是我所需要的,因为它包括了精度总分中小数点前的数字。
例如,使用toStringAsPrecision(3):
0.123456789 rounds to 0.123
9.123456789 rounds to 9.12
98.123456789 rounds to 98.1
987.123456789 rounds to 987
9876.123456789 rounds to 9.88e+3
随着数字大小的增加,小数点后的精度也相应降低。
我认为公认的答案不是完美的解决方案,因为它转换为字符串。
如果你不想转换为字符串并返回双重使用
GetX包中的double.toPrecision(decimalNumber)。
如果你不想为此使用GetX(我强烈推荐GetX,它会改变你的生活),你可以复制和粘贴这个。
当你想使用扩展名时,请记住导入文件。
import 'dart:math';
extension Precision on double {
double toPrecision(int fractionDigits) {
var mod = pow(10, fractionDigits.toDouble()).toDouble();
return ((this * mod).round().toDouble() / mod);
}
}
我认为公认的答案不是完美的解决方案,因为它转换为字符串。
如果你不想转换为字符串并返回双重使用
GetX包中的double.toPrecision(decimalNumber)。
如果你不想为此使用GetX(我强烈推荐GetX,它会改变你的生活),你可以复制和粘贴这个。
当你想使用扩展名时,请记住导入文件。
import 'dart:math';
extension Precision on double {
double toPrecision(int fractionDigits) {
var mod = pow(10, fractionDigits.toDouble()).toDouble();
return ((this * mod).round().toDouble() / mod);
}
}
如果您想要一个双精度结果,将一个IEEE-754二进制浮点数舍入到特定的十进制位数本身就是有问题的。
In the same way that fractions such as 1/3 can't be exactly represented with a finite number of decimal digits, many (really infinitely many) decimal numbers can't be represented with a finite number of binary digits. For example, the decimal number 0.1 cannot be exactly represented in binary. While you could try to round 0.09999 to 0.1, as a double it would actually be "rounded" to 0.1000000000000000055511151231257827021181583404541015625. Most of the other answers that claim to round doubles with decimal precision actually return the nearest representable double.
你能做的就是使字符串表示形式看起来像一个漂亮的四舍五入的数字,这就是double.toStringAsFixed()所做的。这也是为什么当你打印0.100000000…,如果实现试图打印用户友好的值,则可能会看到0.1。然而,不要被愚弄了:double值实际上永远不会精确到0.1,如果你用这样不精确的值重复计算,就会累积错误。
请注意,以上所有内容都是浮点数工作方式所固有的,并不是Dart所特有的。还看到:
浮点数学坏了吗?
如果你不理解上面的解释,Tom Scott也做了一个很好的视频来解释浮点数是如何工作的。
底线:如果关心十进制精度,就不要使用二进制浮点类型。如果你和钱打交道,这一点尤其重要。
相反,你应该使用:
Integers. For example, if you are dealing with currency, instead of using double dollars = 1.23;, use int cents = 123;. Your calculations then always will be exact, and you can convert to the desired units only when displaying them to the user (and likewise can convert in the opposite direction when reading input from the user).
A type designed to represent decimal numbers with arbitrary precision. For example, package:decimal provides a Decimal type. With such a type, some of the other answers (such as multiplying by 100, rounding, and then dividing by 100) then would be appropriate. (But really you should use Decimal.round directly.)