我想用国际单位制将一个整数格式化为3位有效数字。例如:
1 => '1'
999 => '999'
1234 => '1.23k'
1235 => '1.24k'
下面是我对一个函数的粗略修改,仍然不能满足我的所有测试。我遇到的问题涉及检测何时9…
将四舍五入到10…
,因此需要在末尾少一个小数点。
tests = [[9,'9'],[1,'1'],[10,'10'],[99,'99'],[100,'100'],[999,'999'],
[1000,'1.00k'],[1004,'1.00k'],[1009,'1.01k'],[1472,'1.47k'],
[1926,'1.93k'],[1999,'2.00k'],[2000,'2.00k'],[9813,'9.81k'],
[9990,'9.99k'],[9999,'10.0k'],[10000,'10.0k'],[10010,'10.0k'],
[60712,'60.7k'],[98712,'98.7k'],[99949,'99.9k'],[99950,'100k'],
[99999,'100k'],[100000,'100k'],[400499,'400k'],[999499,'999k'],
[999500,'1.00M'],[999999,'1.00M'],[1000000,'1.00M'],
[1234567,'1.23M'],[12345678,'12.3M'],[123456789,'123M']]
tests.forEach( ([n,expected]) => {
const actual = siRound(n)
console.log(n, actual, actual==expected ? '=' : '≠', expected)
})
function siRound(x) {
if (x<1e3) return x+'';
const digits = Math.log10(x) | 0
const tier = digits/3 | 0
let str = (x / 10**(tier*3)).toFixed(2-(digits%3))
// Turn "10.00" into "10.0" and "100.0" into "100"
str = str.replace(/^(.{3})\..+|^(.{4}).+/, '$1$2')
return str + (['','k','M','G','T'])[tier]
}
基于@HereticMonkey指出存在toPrecision()
,这里有一个可行的答案,尽管我觉得有点恶心。如果有人发布了一个答案,我会把它换成一个更干净、完全有效的答案。
// Note: intentionally returns integers below 1,000 unchanged.
// For true precision across all numbers, remove the first line.
function siRound(n, precision=3) {
if (x<1e3) return x+''
let tier = Math.log10(x)/3 | 0
let str = (x / 10**(tier*3)).toPrecision(precision)
if (str>=1e3) str = (x / 10**(++tier*3)).toPrecision(precision)
return str + (['','k','M','G','T','P','E','Z','Y'])[tier]
}
tests = [[9,'9'],[1,'1'],[10,'10'],[99,'99'],[100,'100'],[999,'999'],
[1000,'1.00k'],[1004,'1.00k'],[1009,'1.01k'],[1472,'1.47k'],
[1926,'1.93k'],[1999,'2.00k'],[2000,'2.00k'],[9813,'9.81k'],
[9990,'9.99k'],[9999,'10.0k'],[10000,'10.0k'],[10010,'10.0k'],
[60712,'60.7k'],[98712,'98.7k'],[99949,'99.9k'],[99950,'100k'],
[99999,'100k'],[100000,'100k'],[400499,'400k'],[999499,'999k'],
[999500,'1.00M'],[999999,'1.00M'],[1000000,'1.00M'],
[1234567,'1.23M'],[12345678,'12.3M'],[123456789,'123M']]
const siRound = x => {
if (x < 1e3) {
return x;
}
let roudedX = x;
let tier = 0;
while (roudedX >= 1000) {
roudedX /= 1000;
tier += 1;
}
roudedX = Number.parseFloat(roudedX.toPrecision(3));
if (Math.abs(roudedX - 1e3) < Number.EPSILON) {
roudedX = 1;
tier += 1;
}
return roudedX.toPrecision(3) + ['', 'k', 'M', 'G', 'T'][tier];
}
tests.forEach(([n,expected]) => {
const actual = siRound(n)
console.log(n, actual, actual==expected ? '=' : '≠', expected)
})
让你的方法像递归一样。添加此项,返回前检查:
if (str.length>4) {
siRound(str)
}
tests = [[9,'9'],[1,'1'],[10,'10'],[99,'99'],[100,'100'],[999,'999'],
[1000,'1.00k'],[1004,'1.00k'],[1009,'1.01k'],[1472,'1.47k'],
[1926,'1.93k'],[1999,'2.00k'],[2000,'2.00k'],[9813,'9.81k'],
[9990,'9.99k'],[9999,'10.0k'],[10000,'10.0k'],[10010,'10.0k'],
[60712,'60.7k'],[98712,'98.7k'],[99949,'99.9k'],[99950,'100k'],
[99999,'100k'],[100000,'100k'],[400499,'400k'],[999499,'999k'],
[999500,'1.00M'],[999999,'1.00M'],[1000000,'1.00M'],
[1234567,'1.23M'],[12345678,'12.3M'],[123456789,'123M']]
tests.forEach( ([n,expected]) => {
const actual = siRound(n)
console.log(n, actual, actual==expected ? '=' : '≠', expected)
})
function siRound(x) {
if (x<1e3) return x+'';
const digits = Math.log10(x) | 0
const tier = digits/3 | 0
let str = (x / 10**(tier*3)).toFixed(2-(digits%3))
// Turn "10.00" into "10.0" and "100.0" into "100"
str = str.replace(/^(.{3})\..+|^(.{4}).+/, '$1$2')
if (str.length>4) { ///Add this check
siRound(str)
}
return str + (['','k','M','G','T'])[tier]
}
以下是在格式化模式中使用字符。 编号 类 描述 1 如果数字较小,则显示0。 2 显示忽略前导零的数字。 3 小数分隔符。 4 分组分隔符。 5 指数格式的尾数和指数分隔符。 6 格式分隔符。 7 负数字前缀。 8 将乘以100后的数字显示为百分比。 9 与1000相乘后显示数字为千位。 10 将字符标记为数字前缀/后缀。 11 标记特殊字符的引号。 在这个例子中,我们根据不同的模式来格式化数字。
问题内容: 我想根据测量值打印字符串,但将其限制为2位数字。我为此使用 MeasurementFormatter 。 我期望结果不是。我的错在哪里 问题答案: 您需要将MeasurementFormatter属性unitOption设置为.providedUnit
类提供了各种格式来格式化时间。 要使用方法。 看下面的例子。 在下面的例子中,我们将演示如何使用不同的格式来格式化时间。 文件:IOTester.java - 执行上面示例代码,得到以下结果 -
类提供了各种格式来格式化日期。 以下是一些格式的列表。 在下面的例子中,我们将演示如何使用不同的格式。 文件:IOTester.java - 执行上面示例代码,得到以下结果 -
在本例中,我们根据美国区域设置和丹麦语区域设置格式化货币。 文件:IOTester.java - 执行上面示例代码,得到以下结果 -
使用 toLocaleString() 将浮点数转换为 Decimal mark 格式。 将整数部分转化为用逗号分隔的字符串。 const toDecimalMark = num => num.toLocaleString('en-US'); toDecimalMark(12305030388.9087); // "12,305,030,388.909"