Ответы:
var result = Math.round(original*100)/100;
Специфика , если код не требует пояснений.
редактировать: ... или просто использовать toFixed
, как предложено Тимом Бюте . Забыл это, спасибо (и upvote) за напоминание :)
toFixed()
будет имитировать то, что printf()
делает что-то подобное в C. Однако, toFixed()
и Math.round()
будет обрабатывать округление по-другому. В этом случае toFixed()
эффект Math.floor()
будет аналогичным (если вы заранее умножаете оригинал на 10 ^ n и вызываете toFixed()
с n цифрами). «Правильность» ответа очень зависит от того, что ОП хочет здесь, и оба являются «правильными» по-своему.
Есть функции для округления чисел. Например:
var x = 5.0364342423;
print(x.toFixed(2));
напечатает 5.04.
РЕДАКТИРОВАТЬ: скрипка
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
будет равен"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
…
Будьте осторожны при использовании toFixed()
:
Во-первых, округление числа выполняется с использованием двоичного представления числа, что может привести к неожиданному поведению. Например
(0.595).toFixed(2) === '0.59'
вместо '0.6'
.
Во-вторых, есть ошибка с IE toFixed()
. В IE (по крайней мере, до версии 7, не проверял IE8), верно следующее:
(0.9).toFixed(0) === '0'
Это может быть хорошей идеей следовать предложению kkyy или использовать пользовательскую toFixed()
функцию, например
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
метод в возвращаемое значение, что добавит требуемую точность, например:, return (Math.round(value * power) / power).toFixed(precision);
а также вернет значение в виде строки. В противном случае точность 20 игнорируется для меньших десятичных знаков
toFixed
: обратите внимание, что повышение точности может привести к неожиданным результатам:, (1.2).toFixed(16) === "1.2000000000000000"
while (1.2).toFixed(17) === "1.19999999999999996"
(в Firefox / Chrome; в IE8 последнее не выполняется из-за более низкой точности, которую IE8 может предложить внутри).
(0.598).toFixed(2)
не производит 0.6
. Это производит 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Еще одна проблема, о которой следует знать, это то, что toFixed()
в конце числа могут появляться ненужные нули. Например:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
Идея состоит в том, чтобы очистить вывод, используя RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
Соответствует RegExp
конечным нулям (и, возможно, десятичной запятой), чтобы убедиться, что оно хорошо смотрится и для целых чисел.
humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding
Существует проблема со всеми этими решениями, использующими множители. Решения kkyy и Кристофа, к сожалению, неверны.
Пожалуйста, проверьте свой код для номера 551.175 с двумя десятичными знаками - он округлится до 551,17, а должен быть 551,18 ! Но если вы проверите на экс. 451,175 все будет хорошо - 451,18. Так что трудно обнаружить эту ошибку на первый взгляд.
Проблема с умножением: попробуйте 551.175 * 100 = 55117.49999999999 (ups!)
Поэтому моя идея состоит в том, чтобы обработать его с помощью toFixed () перед использованием Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
это также влияет - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
… Какой бы метод ни использовался, лучше добавить эпсилон перед округлением.
Ключ здесь, я думаю, состоит в том, чтобы сначала правильно округлить, затем вы можете преобразовать его в строку.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Теперь вы можете безопасно отформатировать это значение с помощью toFixed (p). Итак, с вашим конкретным случаем:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Если вы хотите строку без округления, вы можете использовать этот RegEx (возможно, это не самый эффективный способ ... но это действительно легко)
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+'.'+float_part;
}
return float_part ? int_part+'.'+float_part : int_part;
противном случае , если вы прошли Integer, он возвращается номер с точкой в конце (пример ввода: 2100
, выход: 2100.
)
Может быть, вы также хотите десятичный разделитель? Вот функция, которую я только что сделал:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = "";
var part = "";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = '0'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = '.'
part = '0'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = '-'+resposta;
return resposta;
}
Нельзя избежать противоречивого округления цен с фактическим значением x.xx5 с использованием умножения или деления. Если вам необходимо рассчитать правильные цены на стороне клиента, вы должны хранить все суммы в центах. Это связано с характером внутреннего представления числовых значений в JavaScript. Обратите внимание, что Excel страдает от тех же проблем, поэтому большинство людей не заметят мелких ошибок, вызванных этим явлением. Однако ошибки могут накапливаться всякий раз, когда вы складываете много вычисленных значений, существует целая теория, касающаяся порядка вычислений и других методов, чтобы минимизировать ошибку в конечном результате. Чтобы подчеркнуть проблемы с десятичными значениями, обратите внимание, что 0,1 + 0,2 не совсем равно 0,3 в JavaScript, а 1 + 2 равно 3.
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? "-" : " ";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+"."+decStr;
}
prettyFloat(0); // "0.00"
prettyFloat(-1); // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5); // "0.50"
Я использую этот код для форматирования поплавков. Он основан на, toPrecision()
но он удаляет ненужные нули. Я бы приветствовал предложения о том, как упростить регулярное выражение.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Пример использования:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\.?0*$/, '');
result = result.replace(/\.?0*e/, 'e');
result = result.replace('e+', 'e');
return result;
}
document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');