问题描述
在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;
}