QML:格式化数字的精度各不相同,

问题描述

在QML中,我可以使用Number.toLocaleString()格式化数字(我的认语言环境是en_US);但是,给定零参数时,奇怪的是它的行为与所记录的行为不同,尽管这几乎是我想要的。该文档指出:

如果未指定precision,则精度为2。

参数为零时,精度似乎取决于该值的精度:

console.log(123.0.toLocaleString()) // prints "123"
console.log(123.4.toLocaleString()) // prints "123.4"
console.log(123.45.toLocaleString()) // prints "123.45"

如果未指定格式,将使用'f'。

参数为零时,它的行为就像'g'是指定的格式,并且对大数使用指数表示法:

console.log(1000000.0.toLocaleString()) // prints 1e+06

虽然我想在应用程序中以不同的精度格式化数字,但我也想禁用指数格式。但是,如果我将任意数量的参数传递给toLocaleString,则该行为将更改为记录的认2位数字和指定符'f':

console.log(123.0.toLocaleString(Qt.locale())) // prints "123.00"
console.log(1000000.0.toLocaleString(Qt.locale())) // prints "1,000,000.00"

这实际上意味着我不能同时使用'f'格式和不同的精度,除非precision的某些未记录的特殊输入保留了该行为,或者如果我可以以某种方式计算并传递数字:

x = 123.456
console.log(x.toLocaleString(Qt.locale(),'f',decimals(x))) // should print "123.456"

是否有这样的输入,或者我可以编写一些函数decimals来计算小数点后的有效位数?

我知道浮点数是一种二进制格式,不能精确地表示十进制数字/十进制的小数,因此可以接受一些精度,而不是将0.1000000009或0.0999999997视为0.10000000 。我在应用程序中最多使用7位数字,因此我不希望这样的假设引起任何问题。

解决方法

这里是一种算法,可以执行连续的乘法运算,直到达到所需的最大精度,然后检查每个数字并跟踪看到的最后一个非零数字。

function decimals(x) {
  const maxDigits = 8;
  var remaining = x;
  var lastDigit = 0;
  for (var i = 1; i <= maxDigits; i++) {
    // Advance to next digit,cut off leading digits
    remaining = (remaining * 10) % 10

    // Round to account for *.99999 case,modulo 10 to account for 9.999
    if (Math.round(remaining) % 10 != 0) {
      lastDigit = i;
    }
  }
  return lastDigit;
}