Відповіді:
var result = Math.round(original*100)/100;
Особливості , якщо код не пояснює себе.
редагувати: ... або просто використовувати toFixed
, як запропонував Тім Бют . Забув це, спасибі (та нагороду) за нагадування :)
toFixed()
буде імітувати те, що щось подібне printf()
робить у C. Однак, toFixed()
і Math.round()
буде обробляти округлення по-різному. У цьому випадку toFixed()
матиме такий самий ефект, як і у Math.floor()
випадку (якщо ви попередньо помножили оригінал на 10 ^ n і подзвоните toFixed()
з n цифр). "Правильність" відповіді дуже залежить від того, чого хоче тут ОП, і обидва по-своєму "правильні".
Існують функції для округлення чисел. Наприклад:
var x = 5.0364342423;
print(x.toFixed(2));
буде надруковано 5.04.
EDIT: Fiddle
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"
той час, як (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)
… Який би метод не застосовувався, краще додати епсилон перед округленням.
Я думаю, ключовим тут є спочатку правильно закріпити їх, а потім перетворити його на String.
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>');