Am i thiếu cái gì ở đây?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Tại sao không.toFixed()
trả về một chuỗi?
Tôi muốn làm tròn số đến 2 chữ số thập phân.
Am i thiếu cái gì ở đây?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Tại sao không.toFixed()
trả về một chuỗi?
Tôi muốn làm tròn số đến 2 chữ số thập phân.
Câu trả lời:
Nó trả về một chuỗi vì 0,1 và sức mạnh của nó (được sử dụng để hiển thị phân số thập phân), không thể biểu diễn (ít nhất là không có độ chính xác đầy đủ) trong các hệ thống dấu phẩy động nhị phân.
Ví dụ: 0,1 thực sự là 0,000000000000000055511151231257827021181583404541015625 và 0,01 thực sự là 0,01000000000000000020816681711721685132943093776702880859375. (Cảm ơn BigDecimal
vì đã chứng minh quan điểm của tôi. :-P)
Do đó (không có dấu phẩy động thập phân hoặc loại số hữu tỷ), xuất ra nó dưới dạng chuỗi là cách duy nhất để làm cho nó được cắt theo chính xác độ chính xác cần thiết để hiển thị.
toFixed
là một chức năng định dạng, có mục đích duy nhất là chuyển đổi một số thành một chuỗi, định dạng nó bằng cách sử dụng số thập phân được chỉ định. Lý do nó trả về một chuỗi là vì nó được cho là trả về một chuỗi và nếu nó được đặt tên toStringFixed
thay thế, OP sẽ không ngạc nhiên với kết quả. Vấn đề duy nhất ở đây là OP mong đợi nó hoạt động như thế nào Math.round
, mà không cần tham khảo tài liệu tham khảo JS.
Number.prototype.toFixed
là một chức năng được thiết kế để định dạng một số trước khi in ra. Đó là từ gia đình của toString
, toExponential
và toPrecision
.
Để làm tròn một số, bạn sẽ làm điều này:
someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;
// if you need 3 digits, replace 1e2 with 1e3 etc.
// or just copypaste this function to your code:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
.
Hoặc nếu bạn muốn một chức năng giống như bản địa của người Viking , bạn có thể mở rộng nguyên mẫu:
Number.prototype.toFixedNumber = function(digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;
//or even hexadecimal
someNumber = 0xAF309/256 //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";
Tuy nhiên , hãy nhớ rằng việc gây ô nhiễm nguyên mẫu được coi là xấu khi bạn viết mô-đun, vì các mô-đun không nên có bất kỳ tác dụng phụ nào. Vì vậy, đối với một mô-đun, sử dụng chức năng đầu tiên .
type Number
. Điều này là +(anyValue)
luôn trả về một số - ví dụ. +("45")
trả lại 45
, +(new Number(42))
trả lại 42
. Nó giống như gõ mạnh chức năng. Nếu bạn tạo thói quen cho nó, bạn có thể tránh được rất nhiều lỗi :)
someNumber = Math.round( 42.008 * 1e2 ) / 1e2;
không phải 42.01
là nó ~42.0099999999999980
. Lý do: Số 42.01
không tồn tại và được làm tròn đến số hiện có gần nhất. btw, số bằng chứng toPrecision(18)
để in nó với tất cả các chữ số có liên quan.
Tôi đã giải quyết vấn đề này bằng cách thay đổi điều này:
someNumber = someNumber.toFixed(2)
... đến đây:
someNumber = +someNumber.toFixed(2);
Tuy nhiên, điều này sẽ chuyển đổi số thành một chuỗi và phân tích lại nó, điều này sẽ có tác động đáng kể đến hiệu suất. Nếu bạn quan tâm đến hiệu suất hoặc loại an toàn, hãy kiểm tra các câu trả lời khác.
someNumber = Math.round(someNumber * 1e2) / 1e2
! Xem câu trả lời của tôi cho một cách tổng quát hơn.
Tại sao không sử dụng parseFloat
?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
Tất nhiên nó trả về một chuỗi. Nếu bạn muốn làm tròn biến số, bạn sẽ sử dụng Math.round (). Điểm của toFixed là định dạng số có số vị trí thập phân cố định để hiển thị cho người dùng .
Bạn mong đợi điều gì sẽ trở lại khi định dạng số? Nếu bạn có một số, bạn không thể làm bất cứ điều gì với nó vì 2 == 2.0 == 2.00
v.v. vì vậy nó phải là một chuỗi.
Để cung cấp một ví dụ về lý do tại sao nó phải là một chuỗi:
Nếu bạn định dạng 1.toFixed (2), bạn sẽ nhận được '1,00'.
Điều này không giống với 1, vì 1 không có 2 số thập phân.
Tôi biết JavaScript không chính xác là ngôn ngữ hiệu suất , nhưng rất có thể bạn sẽ có hiệu suất tốt hơn để làm tròn nếu bạn sử dụng thứ gì đó như: roundValue = Math.round (value * 100) * 0,01
Bởi vì sử dụng chính của nó là hiển thị số? Nếu bạn muốn làm tròn số, sử dụng Math.round()
với các yếu tố phù hợp.
'42'
là một con số ... mà không phải vậy. Chỉ vì một chuỗi xảy ra chỉ chứa các chữ số không làm cho nó thành một số. Đây không phải là PHP. :-P
Đây là một phiên bản chức năng hơn một chút của câu trả lời m93a
được cung cấp.
const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}
const oneNumber = 10.12323223
const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123
// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12