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

随着数字大小的增加,小数点后的精度也相应降低。


当前回答

如果使用动态类型的数据。你可以使用它。

 typeDecimal(data) => num.parse(data.toString()).toStringAsFixed(2);

其他回答

double value = 2.8032739273;
String formattedValue = value.toStringAsFixed(3);
void main() {
  int decimals = 2;
  int fac = pow(10, decimals);
  double d = 1.234567889;
  d = (d * fac).round() / fac;
  print("d: $d");
}

打印: 1.23

使用Dart Extension方法修改@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

从来没有想过这在Dart是如此复杂,但这是我的解决方案:

double truncateDouble(double val, int decimals) {
    String valString = val.toString();
    int dotIndex = valString.indexOf('.');

    // not enough decimals
    int totalDecimals = valString.length - dotIndex - 1;
    if (totalDecimals < decimals) {
      decimals = totalDecimals;
    }

    valString = valString.substring(0, dotIndex + decimals + 1);

    return double.parse(valString);
  }

var val = truncateDouble(44.999, 2);

如果你想要使用特殊的舍入。您可以尝试这个函数(舍入)。

void main(List<String> arguments) {
list.map((e) {
 log('list1');
 rounding(e, 0.05);
 rounding(e, 0.1);
 rounding(e, 0.2);
 rounding(e, 0.25);
 rounding(e, 0.5);
 rounding(e, 1);
 rounding(e, 10);
}).toList();
list2.map((e) {
 log('list2');
 rounding(e, 0.05);
 rounding(e, 0.1);
 rounding(e, 0.2);
 rounding(e, 0.25);
 rounding(e, 0.5);
 rounding(e, 1);
 rounding(e, 10);
}).toList();
}

const list = [1.11, 1.22, 1.33, 1.44, 1.55, 1.66, 1.77, 1.88, 1.99];

const list2 = [2.19, 3.28, 4.37, 5.46, 6.55, 7.64, 8.73, 9.82, 10.91];

void rounding(double price, double count) {
log('-----------------------');
log('price: $price, count: $count');
double _priceRemainder = price % count;
double _someDiff = count / _priceRemainder;
log('_price: ${_priceRemainder.toStringAsFixed(2)}');
log('_pricePlus: ${_someDiff.toStringAsFixed(2)}');
if (_someDiff.toStringAsFixed(2) == '1.00') {
 log('_someDiff = 1');
} else if (_someDiff > 1 && _someDiff <= 2 ||
   _someDiff.toStringAsFixed(2) == '2.00') {
 log('_someDiff > 1 && _someDiff <= 2 || _someDiff.toStringAsFixed(2) == 2.00');
 log('ceilToDouble: $price: ${(price + (count - _priceRemainder)).toStringAsFixed(2)}');
 log('floorToDouble: $price: ${(price - _priceRemainder).toStringAsFixed(2)}');
 log('roundToDouble: $price: ${(price + (count - _priceRemainder)).toStringAsFixed(2)}');
} else if (_someDiff > 2) {
 log('_someDiff > 2');
 log('ceilToDouble: $price: ${(price + (count - _priceRemainder)).toStringAsFixed(2)}');
 log('floorToDouble: $price: ${(price - _priceRemainder).toStringAsFixed(2)}');
 log('roundToDouble: $price: ${(price - _priceRemainder).toStringAsFixed(2)}');
}
log('-----------------------');
}

调试控制台:


[log] price: 10.91, count: 0.05
[log] _price: 0.01
[log] _pricePlus: 5.00
[log] _someDiff > 2
[log] ceilToDouble: 10.91: 10.95
[log] floorToDouble: 10.91: 10.90
[log] roundToDouble: 10.91: 10.90
2
[log] -----------------------
[log] price: 10.91, count: 0.1
[log] _price: 0.01
[log] _pricePlus: 10.00
[log] _someDiff > 2
[log] ceilToDouble: 10.91: 11.00
[log] floorToDouble: 10.91: 10.90
[log] roundToDouble: 10.91: 10.90
2
[log] -----------------------
[log] price: 10.91, count: 0.2
[log] _price: 0.11
[log] _pricePlus: 1.82
[log] _someDiff > 1 && _someDiff <= 2 || _someDiff.toStringAsFixed(2) == 2.00
[log] ceilToDouble: 10.91: 11.00
[log] floorToDouble: 10.91: 10.80
[log] roundToDouble: 10.91: 11.00
2
[log] -----------------------
[log] price: 10.91, count: 0.25
[log] _price: 0.16
[log] _pricePlus: 1.56
[log] _someDiff > 1 && _someDiff <= 2 || _someDiff.toStringAsFixed(2) == 2.00
[log] ceilToDouble: 10.91: 11.00
[log] floorToDouble: 10.91: 10.75
[log] roundToDouble: 10.91: 11.00
2
[log] -----------------------
[log] price: 10.91, count: 0.5
[log] _price: 0.41
[log] _pricePlus: 1.22
[log] _someDiff > 1 && _someDiff <= 2 || _someDiff.toStringAsFixed(2) == 2.00
[log] ceilToDouble: 10.91: 11.00
[log] floorToDouble: 10.91: 10.50
[log] roundToDouble: 10.91: 11.00
2
[log] -----------------------
[log] price: 10.91, count: 1.0
[log] _price: 0.91
[log] _pricePlus: 1.10
[log] _someDiff > 1 && _someDiff <= 2 || _someDiff.toStringAsFixed(2) == 2.00
[log] ceilToDouble: 10.91: 11.00
[log] floorToDouble: 10.91: 10.00
[log] roundToDouble: 10.91: 11.00
2
[log] -----------------------
[log] price: 10.91, count: 10.0
[log] _price: 0.91
[log] _pricePlus: 10.99
[log] _someDiff > 2
[log] ceilToDouble: 10.91: 20.00
[log] floorToDouble: 10.91: 10.00
[log] roundToDouble: 10.91: 10.00