Из-за ошибок, обнаруженных JasperV - хорошие моменты!- Я переписал свой старый код.Я предполагаю, что когда-либо использовал это только для положительных значений с двумя десятичными знаками.
В зависимости от того, чего вы пытаетесь достичь, вы можете захотеть округлить или нет, поэтому здесь две версии разделены на это деление.
Сначала, с округлением.
Я ввел метод toFixed()
, так как он лучше обрабатывает округление до определенных десятичных разрядов и хорошо поддерживает.Однако это замедляет процесс.
Эта версия по-прежнему отделяет десятичную дробь, но использует метод, отличный от предыдущего.Часть w|0
удаляет десятичную дробь.Для получения дополнительной информации об этом, это хороший ответ .Затем оставляется целое число, сохраняется его в 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: '');
};
В фрагменте нижеВы можете редактировать номера, чтобы проверить себя.
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()
однако, оба из которых являются очень медленными по сравнению.И хотя я узнал что-то новое из ответа Майкла о 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?" />
В скором времени я обновлю демонстрацию фрагмента на странице, но пока вот скрипка:
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
без десятичных знаков):
'1' + ',000,000' + '.42'
Fiddlesticks
http://jsfiddle.net/XC3sS/