Javascript 用国际单位制将数字格式化为三个sig图

Javascript 用国际单位制将数字格式化为三个sig图,javascript,Javascript,我想用国际单位制将一个整数格式化为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

我想用国际单位制将一个整数格式化为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'],[9994999,'999k'],
[999500,'1.00M'],[999999,'1.00M'],[1000000,'1.00M'],
[1234567,'123万'],[12345678,'123万'],[123456789,'123M']
tests.forEach([n,预期])=>{
常数实际值=siRound(n)
log(n,实际值,实际值==预期值?'=':'≠', 预期的)
})
函数siRound(x){

如果(x使您的方法像递归一样。添加此项,请在返回前检查:

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'],[9994999,'999k'],
[999500,'1.00M'],[999999,'1.00M'],[1000000,'1.00M'],
[1234567,'123万'],[12345678,'123万'],[123456789,'123M']
tests.forEach([n,预期])=>{
常数实际值=siRound(n)
log(n,实际值,实际值==预期值?'=':'≠', 预期的)
})
函数siRound(x){
如果(x4){///添加此检查
siRound(str)
}
返回str+(['','k','M','G','T'])[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'],[9994999,'999k'],
[999500,'1.00M'],[999999,'1.00M'],[1000000,'1.00M'],
[1234567,'123万'],[12345678,'123万'],[123456789,'123M']
常数siRound=x=>{
if(x<1e3){
返回x;
}
设roudedX=x;
设tier=0;
而(roudedX>=1000){
roudedX/=1000;
第+=1级;
}
roudedX=Number.parseFloat(roudedX.toPrecision(3));
if(数学绝对值(roudedX-1e3){
常数实际值=siRound(n)
log(n,实际值,实际值==预期值?'=':'≠', 预期的)

})
基于@HereticMonkey指出的存在,这里有一个有效的答案,尽管我觉得有点恶心。如果有人发布了一个答案,我会把它换成一个更干净、完全有效的答案

//注意:有意返回1000以下的整数,但保持不变。
//要获得所有数字的真实精度,请删除第一行。
函数SIROND(n,精度=3){
如果(x=1e3)str=(x/10**(++第3层)).toPrecision(精度)
返回str+(['','k','M','G','T','P','E','Z','Y'])[tier]
}

您是否尝试过:
Number.prototype.toFixed(3)
?@Mr.polywhill
(1234).toFixed(3)=>“1234.000”
,而不是
1.23k
。如您所见,我的代码已经使用了
toFixed()
在某些方面。听起来你想要
toPrecision
一只la@HereticMonkey,这绝对是解决这个问题的一个有用的部分,谢谢!它本身不是一个很好的答案,但几乎就在那里了。+1是一个有趣的黑客,但是-1是因为它不起作用。仍然有
999500
1000k
而不是
1.00M
。你不需要通过递归调用
siRound()
来删除任何内容,因为您不会对调用结果执行任何操作。