在小数点后如何将Dart中的double舍入到给定的精度?


111

给定一个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

随着数量的增加,我相应地失去了小数点后的精度。

Answers:


193

请参阅num.toStringAsFixed()的文档。

字符串toStringAsFixed(int fractionDigits)

返回其小数点字符串表示形式。

在计算字符串表示形式之前,将其转换为double。

  • 如果此方法的绝对值大于或等于10 ^ 21,则此方法返回由this.toStringAsExponential()计算的指数表示形式。

例子:

1000000000000000000000.toStringAsExponential(3); // 1.000e+21
  • 否则,结果将是最接近的字符串表示形式,其精确到小数点后的fractionDigits位。如果fractionDigits等于0,则省略小数点。

参数fractionDigits必须是一个满足以下条件的整数:0 <= fractionDigits <= 20。

例子:

1.toStringAsFixed(3);  // 1.000
(4321.12345678).toStringAsFixed(3);  // 4321.123
(4321.12345678).toStringAsFixed(5);  // 4321.12346
123456789012345678901.toStringAsFixed(3);  // 123456789012345683968.000
1000000000000000000000.toStringAsFixed(3); // 1e+21
5.25.toStringAsFixed(0); // 5

必须被接受+参考+解释+示例
Kohls

1
我认为是toStringAsFixed()由于其不一致而使用的舍入方法。例如,尝试5.550.toStringAsFixed(1)
brendan

在这种情况下,当四舍五入到0位时也要注意,因为表达式返回的int是a而不是a double,例如num.parse(50.123.toStringAsFixed(0)) is int-可以通过.toDouble()在其末尾添加来解决此问题。
阿布卡

62

num.toStringAsFixed()四舍五入。这使您将num(n)转换为具有所需小数位数(2)的字符串,然后在一行漂亮的代码行中将其解析回num:

n = num.parse(n.toStringAsFixed(2));

6
这是最快的方法。但是愚蠢的是,飞镖没有直接的方法可以做到这一点
ThinkDigital

1
扩展方法: extension NumberRounding on num { num toPrecision(int precision) { return num.parse((this).toStringAsFixed(precision)); } }
Vit Veres,

26

上述解决方案没有适当舍入数字。我用:

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

确认,这可以dp(5.550, 1)正确舍入5.6-与最流行的答案不同,后者给出了5.5@brendan指出的稍微错误的答案。
阿布卡

对于DP不起作用(73.4750,2)返回73.47,而不是73.48 calculatorsoup.com/calculators/math/... 看看这个链接
深沙阿

20
void main() {
  int decimals = 2;
  int fac = pow(10, decimals);
  double d = 1.234567889;
  d = (d * fac).round() / fac;
  print("d: $d");
}

版画:1.23


1
这是目前最好的方法。四舍五入到0.01之类的精度本身并不是两倍,这并非易事。结果甚至可能根本无法表示为两倍。我强烈建议对小数精​​度很重要的任何事物(例如,金钱)使用整数。
lrn

1
还值得指出的是,如果编译为js,则Dart整数也会开始失去精度,您需要使用以下软件包:pub.dartlang.org/packages/bignum
Greg Lowe

这种方法感觉像是目前最好,最优雅的方法。
乔凡尼

不能将double分配给int错误发生在第3行
Gayan Pathirage'Feb 4'19


13

要在小数点后将Dart中的double舍入到给定的精度,您可以在darttoStringAsFixed()方法中使用内置解决方案,但必须将其转换回double

void main() {
  double step1 = 1/3;  
  print(step1); // 0.3333333333333333
  
  String step2 = step1.toStringAsFixed(2); 
  print(step2); // 0.33 
  
  double step3 = double.parse(step2);
  print(step3); // 0.33
}


8

使用Dart扩展方法对@andyw的修改后的答案:

extension Precision on double {
    double toPrecision(int fractionDigits) {
        double mod = pow(10, fractionDigits.toDouble());
        return ((this * mod).round().toDouble() / mod);
    }
}

用法:

var latitude = 1.123456;
var latitudeWithFixedPrecision = latitude.toPrecision(3); // Outputs: 1.123

6

您可以使用toStringAsFixed以便在小数点后显示有限的数字。toStringAsFixed返回小数点字符串表示形式。toStringAsFixed接受一个称为的参数fraction Digits,即要显示的小数点后多少位数。这是使用方法。

double pi = 3.1415926;
const val = pi.toStringAsFixed(2); // 3.14

6

定义扩展名:

extension Ex on double {
  double toPrecision(int n) => double.parse(toStringAsFixed(n));
}

用法:

void main() {
  double d = 2.3456789;
  double d1 = d.toPrecision(1); // 2.3
  double d2 = d.toPrecision(2); // 2.35
  double d3 = d.toPrecision(3); // 2.345
}

2

我使用toStringAsFixed()方法将数字四舍五入到小数点EX之后的特定数字:double num = 22.48132906,当我四舍五入为这样的两个数字时:print(num.toStringAsFixed(2);

它印了22.48

当我四舍五入到一个数字时..打印22.5


2

上述解决方案并非在所有情况下都适用。解决此问题的有效方法是将您的数字四舍五入(0.5到1或0.49到0),并且不带任何小数

输入: 12.67

double myDouble = 12.67;
var myRoundedNumber; // Note the 'var' datatype

// Here I used 1 decimal. You can use another value in toStringAsFixed(x)
myRoundedNumber = double.parse((myDouble).toStringAsFixed(1));
myRoundedNumber = myRoundedNumber.round();

print(myRoundedNumber);

输出: 13

此链接也有其他解决方案


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.