由于 JasperV 发现的错误 - 好点! — 我重写了我的旧代码。我想我只将它用于带有两位小数的正值。
根据您要达到的目标,您可能需要舍入或不舍入,因此这里有两个版本跨越该鸿沟。
首先是四舍五入。
我已经介绍了toFixed() 方法,因为它可以更好地准确地处理四舍五入到特定的小数位并且得到很好的支持。但是,它确实会减慢速度。
这个版本仍然分离小数,但使用与以前不同的方法。 w|0 部分删除小数点。有关这方面的更多信息,这是good answer。然后留下剩余的整数,将其存储在 k 中,然后再次从原始数字中减去它,留下小数。
另外,如果我们要考虑负数,我们需要 while 循环(跳过三位数)直到我们点击 b。这在处理负数时被计算为 1,以避免放置类似-,100.00
循环的其余部分与之前相同。
function formatThousandsWithRounding(n, dp){
var w = n.toFixed(dp), k = w|0, b = n < 0 ? 1 : 0,
u = Math.abs(w-k), d = (''+u.toFixed(dp)).substr(2, dp),
s = ''+k, i = s.length, r = '';
while ( (i-=3) > b ) { r = ',' + s.substr(i, 3) + r; }
return s.substr(0, i + 3) + r + (d ? '.'+d: '');
};
您可以在下面的 sn-p 中编辑数字来测试自己。
function formatThousandsWithRounding(n, dp){
var w = n.toFixed(dp), k = w|0, b = n < 0 ? 1 : 0,
u = Math.abs(w-k), d = (''+u.toFixed(dp)).substr(2, dp),
s = ''+k, i = s.length, r = '';
while ( (i-=3) > b ) { r = ',' + s.substr(i, 3) + r; }
return s.substr(0, i + 3) + r + (d ? '.'+d: '');
};
var dp;
var createInput = function(v){
var inp = jQuery('<input class="input" />').val(v);
var eql = jQuery('<span> = </span>');
var out = jQuery('<div class="output" />').css('display', 'inline-block');
var row = jQuery('<div class="row" />');
row.append(inp).append(eql).append(out);
inp.keyup(function(){
out.text(formatThousandsWithRounding(Number(inp.val()), Number(dp.val())));
});
inp.keyup();
jQuery('body').append(row);
return inp;
};
jQuery(function(){
var numbers = [
0, 99.999, -1000, -1000000, 1000000.42, -1000000.57, -1000000.999
], inputs = $();
dp = jQuery('#dp');
for ( var i=0; i<numbers.length; i++ ) {
inputs = inputs.add(createInput(numbers[i]));
}
dp.on('input change', function(){
inputs.keyup();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="dp" type="range" min="0" max="5" step="1" value="2" title="number of decimal places?" />
现在是另一个版本,没有四舍五入。
这采用不同的方法并试图避免数学计算(因为这可能会引入舍入或舍入错误)。如果您不想要四舍五入,那么您只是将事物作为字符串处理,即转换为两位小数的 1000.999 将永远是 1000.99 而不是 1001.00。
这种方法避免了使用.split() 和RegExp(),但是,这两者相比起来都非常慢。虽然我从 Michael 关于toLocaleString 的回答中学到了一些新的东西,但我也很惊讶地发现它——在某种程度上——是所有方法中最慢的(至少在 Firefox 和 Chrome;Mac OSX 中)。
使用lastIndexOf(),我们可以找到可能存在的小数点,从那里其他一切都几乎相同。在需要的地方用额外的 0 保存填充。此代码限制为小数点后 5 位。在我的测试中,这是更快的方法。
var formatThousandsNoRounding = function(n, dp){
var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,
i = s.lastIndexOf('.'), j = i == -1 ? l : i,
r = e, d = s.substr(j+1, dp);
while ( (j-=3) > b ) { r = ',' + s.substr(j, 3) + r; }
return s.substr(0, j + 3) + r +
(dp ? '.' + d + ( d.length < dp ?
('00000').substr(0, dp - d.length):e):e);
};
var formatThousandsNoRounding = function(n, dp){
var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,
i = s.lastIndexOf('.'), j = i == -1 ? l : i,
r = e, d = s.substr(j+1, dp);
while ( (j-=3) > b ) { r = ',' + s.substr(j, 3) + r; }
return s.substr(0, j + 3) + r +
(dp ? '.' + d + ( d.length < dp ?
('00000').substr(0, dp - d.length):e):e);
};
var dp;
var createInput = function(v){
var inp = jQuery('<input class="input" />').val(v);
var eql = jQuery('<span> = </span>');
var out = jQuery('<div class="output" />').css('display', 'inline-block');
var row = jQuery('<div class="row" />');
row.append(inp).append(eql).append(out);
inp.keyup(function(){
out.text(formatThousandsNoRounding(Number(inp.val()), Number(dp.val())));
});
inp.keyup();
jQuery('body').append(row);
return inp;
};
jQuery(function(){
var numbers = [
0, 99.999, -1000, -1000000, 1000000.42, -1000000.57, -1000000.999
], inputs = $();
dp = jQuery('#dp');
for ( var i=0; i<numbers.length; i++ ) {
inputs = inputs.add(createInput(numbers[i]));
}
dp.on('input change', function(){
inputs.keyup();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="dp" type="range" min="0" max="5" step="1" value="2" title="number of decimal places?" />
我很快会更新一个页面内的 sn-p 演示,但现在这里是一个小提琴:
https://jsfiddle.net/bv2ort0a/2/
旧方法
为什么要为此使用 RegExp? — 当牙签可以使用时不要使用锤子,即使用字符串操作:
var formatThousands = function(n, dp){
var s = ''+(Math.floor(n)), d = n % 1, i = s.length, r = '';
while ( (i -= 3) > 0 ) { r = ',' + s.substr(i, 3) + r; }
return s.substr(0, i + 3) + r +
(d ? '.' + Math.round(d * Math.pow(10, dp || 2)) : '');
};
走过
formatThousands( 1000000.42 );
先去掉小数:
s = '1000000', d = ~ 0.42
从字符串的末尾向后工作:
',' + '000'
',' + '000' + ',000'
通过添加剩余前缀和小数后缀来完成(四舍五入到dp no.小数点):
'1' + ',000,000' + '.42'
提琴手
http://jsfiddle.net/XC3sS/