Câu trả lời:
var result = Math.round(original*100)/100;
Các chi tiết cụ thể , trong trường hợp mã không tự giải thích.
chỉnh sửa: ... hoặc chỉ sử dụng toFixed
, theo đề xuất của Tim Büthe . Quên cái đó đi, cảm ơn (và một upvote) để nhắc nhở :)
toFixed()
sẽ bắt chước những gì giống như printf()
trong C. Tuy nhiên, toFixed()
và Math.round()
sẽ xử lý làm tròn khác nhau. Trong trường hợp này, toFixed()
sẽ có cùng loại hiệu ứng Math.floor()
(với điều kiện bạn nhân số gốc với 10 ^ n trước đó và gọi toFixed()
bằng n chữ số). "Tính chính xác" của câu trả lời phụ thuộc rất nhiều vào những gì OP muốn ở đây và cả hai đều "chính xác" theo cách riêng của họ.
Có chức năng để làm tròn số. Ví dụ:
var x = 5.0364342423;
print(x.toFixed(2));
sẽ in 5.04.
EDIT: Fiddle
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
sẽ bằng nhau"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
...
Cẩn thận khi sử dụng toFixed()
:
Đầu tiên, làm tròn số được thực hiện bằng cách sử dụng biểu diễn nhị phân của số, điều này có thể dẫn đến hành vi không mong muốn. Ví dụ
(0.595).toFixed(2) === '0.59'
thay vì '0.6'
.
Thứ hai, có một lỗi IE với toFixed()
. Trong IE (ít nhất là tới phiên bản 7, không kiểm tra IE8), điều sau đây đúng:
(0.9).toFixed(0) === '0'
Có thể là một ý tưởng tốt để làm theo đề xuất của kkyy hoặc sử dụng toFixed()
chức năng tùy chỉnh , ví dụ:
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
phương thức gốc trong giá trị trả về, sẽ thêm số lượng chính xác cần thiết, ví dụ: return (Math.round(value * power) / power).toFixed(precision);
và cũng trả về giá trị dưới dạng chuỗi. Mặt khác, độ chính xác của 20 bị bỏ qua cho các số thập phân nhỏ hơn
toFixed
: lưu ý rằng việc tăng độ chính xác có thể mang lại kết quả không mong muốn:, (1.2).toFixed(16) === "1.2000000000000000"
trong khi (1.2).toFixed(17) === "1.19999999999999996"
(trong Firefox / Chrome; trong IE8, cái sau không giữ được do độ chính xác thấp hơn mà IE8 có thể cung cấp trong nội bộ).
(0.598).toFixed(2)
không sản xuất 0.6
. Nó tạo ra 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Một vấn đề nữa cần lưu ý, đó là toFixed()
có thể tạo ra các số không cần thiết ở cuối số. Ví dụ:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
Ý tưởng là để làm sạch đầu ra bằng cách sử dụng RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
Các RegExp
số không khớp với các số 0 ở cuối (và tùy ý là dấu thập phân) để đảm bảo nó cũng tốt cho các số nguyên.
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
Có một vấn đề với tất cả những giải pháp nổi xung quanh bằng cách sử dụng bội số. Cả hai giải pháp của kkyy và Christoph đều sai.
Vui lòng kiểm tra mã của bạn cho số 551.175 với 2 chữ số thập phân - nó sẽ làm tròn thành 551,17 trong khi đó sẽ là 551,18 ! Nhưng nếu bạn kiểm tra cho ex. 451.175 sẽ ổn thôi - 451,18. Vì vậy, thật khó để phát hiện ra lỗi này ngay từ cái nhìn đầu tiên.
Vấn đề là nhân lên: thử 551.175 * 100 = 55117.49999999999 (up!)
Vì vậy, ý tưởng của tôi là xử lý nó với toFixed () trước khi sử dụng Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
cũng bị ảnh hưởng - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
Phương pháp nào được sử dụng, tốt hơn là thêm một epsilon trước khi làm tròn.
Chìa khóa ở đây tôi đoán là làm tròn chính xác trước, sau đó bạn có thể chuyển đổi nó thành Chuỗi.
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
Bây giờ bạn có thể định dạng giá trị này một cách an toàn với toFixed (p). Vì vậy, với trường hợp cụ thể của bạn:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Nếu bạn muốn chuỗi không có vòng, bạn có thể sử dụng RegEx này (có thể không phải là cách hiệu quả nhất ... nhưng thực sự dễ dàng)
(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;
nếu không, nếu bạn vượt qua Integer, nó sẽ trả về số có dấu chấm ở cuối (ví dụ đầu vào : 2100
, đầu ra 2100.
:)
Có lẽ bạn cũng sẽ muốn phân tách thập phân? Đây là một chức năng tôi vừa thực hiện:
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;
}
Không có cách nào để tránh làm tròn không nhất quán cho giá với x.xx5 là giá trị thực bằng cách sử dụng phép nhân hoặc chia. Nếu bạn cần tính toán giá chính xác phía khách hàng, bạn nên giữ tất cả số tiền tính bằng xu. Điều này là do bản chất của biểu diễn bên trong của các giá trị số trong JavaScript. Lưu ý rằng Excel bị các vấn đề tương tự, vì vậy hầu hết mọi người sẽ không nhận thấy các lỗi nhỏ do hiện tượng này gây ra. Tuy nhiên, lỗi có thể tích lũy bất cứ khi nào bạn cộng nhiều giá trị được tính toán, có toàn bộ lý thuyết xung quanh vấn đề này liên quan đến thứ tự tính toán và các phương pháp khác để giảm thiểu lỗi trong kết quả cuối cùng. Để nhấn mạnh về các vấn đề với giá trị thập phân, xin lưu ý rằng 0,1 + 0,2 không chính xác bằng 0,3 trong JavaScript, trong khi 1 + 2 bằng 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"
Tôi sử dụng mã này để định dạng nổi. Nó dựa trên toPrecision()
nhưng nó tước các số không cần thiết. Tôi sẽ hoan nghênh các đề xuất về cách đơn giản hóa regex.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Ví dụ sử dụng:
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>');