2015-05-14 49 views
7

Tôi đang phải đối mặt với một vấn đề với Math.floor chức năng javascript cho kịch bản dưới đây:Javascript Math.floor vấn đề giữa phạm vi cụ thể của số

1) từ giá trị betwwen 8192 và 10.484,

if I type 8192.8 -> The Math.floor converts it into 8192.79 

    if I type 8192.88 -> The Math.floor converts it into 8192.87 

    if I type 8192.3 -> The Math.floor converts it into 8192.29 

Phần lạ là ngoại trừ phạm vi được đưa ra ở trên hàm hoạt động tốt.

HTML: 
<div data-bind="text: popIncrease"></div> 
<input type="text" data-bind="value: userInput, valueUpdate: 'afterkeydown'" /> 

Javascript: 

var ViewModel = function() { 
var _self = this; 
_self.userInput = ko.observable(); 
_self.popIncrease = ko.computed(function() { 

     return parseFloat((Math.floor(_self.userInput() * 100)/100)).toFixed(2); 
}); 
}; 

ko.applyBindings(new ViewModel()); 

jsfiddle: https://jsfiddle.net/91z5bdy4/1/

Khi tôi thay đổi 100 với 1000 nó đã giải quyết được lỗi nhưng tôi không hiểu tại sao điều này xảy ra trên địa điểm đầu tiên?

+3

thể trùng lặp của [Is điểm nổi toán học bị hỏng?] (http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – suish

+0

Thực tế không có gì để làm với knockout hoặc jquery. Bạn đang thực sự cố gắng làm gì? Nó có vẻ như bạn muốn làm tròn một số đến 2 chữ số thập phân sau đó hiển thị nó với 2 chữ số thập phân. Việc chuyển một số tới * parseFloat * là thừa (nó đã là một số). Một biểu thức không nên được bao bọc trong các dấu ngoặc kép như '((…))', một tập hợp thừa. Tại sao không 'trả về parseFloat (_self.userInput()). ToFixed (2)'? – RobG

+0

8192.8 * 100 === 819279.9999999999, chúc may mắn với điểm số nổi. – floribon

Trả lời

0

Thứ tự sàn/phân tích của bạn có vẻ không phù hợp với tôi.

Hãy thử:

return Math.floor(parseFloat(_self.userInput())).toFixed(2); 

Mặc dù ý thức được rằng 1,999999999999999999999999999999 cho 2.00 sử dụng trên; điều này là do các số dấu phẩy động không thể đại diện cho tất cả các giá trị chính xác.

+0

1,999999999 cho 2,00 vì '.toFixed (2)' làm tròn đến hai chữ số thập phân. Có vấn đề với độ chính xác của dấu phẩy động, nhưng ví dụ của bạn không phải là vấn đề phát sinh. – jfriend00

+0

@ jfriend00 Nó có thể là nhiều hơn để làm với 'parseFloat (" 1.9999999999999999999999999 ") === 2' là' true'. – Paul

+0

@ Paul — và '(1.999) .toFixed (2) === '2.00''. ;-) – RobG

1

Bạn chỉ có thể chuyển sang chế độ này:

return parseFloat(_self.userInput()).toFixed(2); 

phiên bản của jsFiddle của bạn làm việc: https://jsfiddle.net/jfriend00/5rLL04Lk/


Hoặc, nếu bạn muốn làm việc xung quanh một số các đặc tính của .toFixed(), bạn có thể sử dụng này:

return (Math.round(_self.userInput() * 100)/100).toFixed(2); 

Working jsFiddle: https://jsfiddle.net/jfriend00/xx2aj2L0/

Giải pháp này vượt qua cả ba trường hợp kiểm tra của bạn.

+0

Ngoại trừ việc làm tròn trong * toFixed * là lỗi ... '(3.335) .toFixed (2)' cho '3,33' trong đó '3,34' có thể được mong đợi. – RobG

+0

@RobG - cung cấp một giải pháp khác hoạt động xung quanh sự kỳ quặc '.toFixed (2)'. – jfriend00

+0

Tất nhiên vẫn còn lỗi cũ trong việc thực hiện IE * toFixed * (jScript 5.8), nhưng có lẽ nó đã được sửa. ;-) – RobG

1

Nó không phải là Math.floor() gây ra sự cố, đó là sự không chính xác của số học dấu phẩy động. Khi bạn nhân 8192.8 bởi 100, bạn nhận được 819279.9999999999.

Có lẽ bạn chỉ nên vận dụng nó như là một chuỗi:

function floorString(str) { 
    var pos = str.indexOf('.'); 
    return (pos >= 0) ? ((str + '00').slice(0, pos + 3)) : (str + '.00'); 
} 

jsfiddle

+0

Và làm tròn xảy ra ...? – RobG

+1

@RobG - Tôi có hiểu sai câu hỏi không? Có vẻ như OP chỉ cắt ngắn số, chứ không làm tròn số. –

+0

Không, tôi. :-) Tôi đã giả định rằng OP đã cố gắng để làm tròn số lượng, không chỉ cắt ngắn nó ở 2 nơi. – RobG

0

nhau mà không sử dụng một hàm Math (2 dòng mà không cần định dạng)

function floorString(str) { 
    var matches = str.match(/([\d]+(\.[\d]{0,2}))/); 
    return matches === null || matches[2].length === 1 ? 
      (str + ".00").replace("..", ".") : 
      matches[2].length < 3 ? 
       matches[0] + "00".substr(3 - matches[2].length) : 
       matches[0]; 
} 
Các vấn đề liên quan