toStringAsFixed()返回Dart中给定数字的四舍五入值



我想在Dart中得到double的小数点后一位。我使用toStringAsFixed()方法来获取它,但它返回一个四舍五入值。

double d1 = 1.151;
double d2 = 1.150;
print('$d1 is ${d1.toStringAsFixed(1)}');
print('$d2 is ${d2.toStringAsFixed(1)}');
Console output:
1.151 is 1.2
1.15 is 1.1

如果没有四舍五入值,我怎么能得到它?像1.11.151也一样。提前谢谢。

Not舍入对我来说似乎很有问题1,但是如果真的想要截断字符串表示而不舍入,那么我会取字符串表示,找到小数点,并创建适当的子字符串。

有几个潜在的陷阱:

  • 该值可能太大,以至于其正常字符串表示为指数形式。注意,对于如此大的数字,double.toStringAsFixed只是返回指数形式,所以可能做同样的事情。
  • 该值可能很小,其正常字符串表示形式为指数形式。double.toStringAsFixed已经处理了这个问题,所以不要使用double.toString,而是使用double.toStringAsFixed和最大小数位数。
  • 值可能根本没有小数点(例如NaN, +infinity, -infinity)。直接返回这些值。
extension on double {
// Like [toStringAsFixed] but truncates (toward zero) to the specified
// number of fractional digits instead of rounding.
String toStringAsTruncated(int fractionDigits) {
// Require same limits as [toStringAsFixed].
assert(fractionDigits >= 0);
assert(fractionDigits <= 20);

if (fractionDigits == 0) {
return truncateToDouble().toString();
}
// [toString] will represent very small numbers in exponential form.
// Instead use [toStringAsFixed] with the maximum number of fractional
// digits.
var s = toStringAsFixed(20);
// [toStringAsFixed] will still represent very large numbers in
// exponential form.
if (s.contains('e')) {
// Ignore values in exponential form.
return s;
}
// Ignore unrecognized values (e.g. NaN, +infinity, -infinity).
var i = s.indexOf('.');
if (i == -1) {
return s;
}
return s.substring(0, i + fractionDigits + 1);
}
}
void main() {
var values = [
1.151,
1.15,
1.1999,
-1.1999,
1.0,
1e21,
1e-20,
double.nan,
double.infinity,
double.negativeInfinity,
];
for (var v in values) {
print(v.toStringAsTruncated(1));
}
}

另一种可能考虑的方法是乘以pow(10, fractionalDigits),使用double.truncateToDouble,除以前面使用的10的幂,然后使用.toStringAsFixed(fractionalDigits)。这可能适用于人类尺度的值,但由于浮点运算的精度损失,对于非常大的值可能会产生意想不到的结果。(如果您使用package:decimal而不是double,则此方法可以工作。)


1不舍入似乎特别糟糕,因为使用doubles来表示以10为基数的小数本质上是不精确的。例如,由于IEEE-754最接近0.7的双精度浮点数是0.69999999999999999999555910790149937383830547332763671875,您真的希望0.7.toStringAsTruncated(1)返回'0.6'而不是'0.7'吗?

最新更新