Javascript Math.floor problem between a specific range of numbers

I am having a problem with the Math.floor javascript function for the script below:

1) from a value between 8192 and 10484,

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 

The strange part is that, with the exception of the range indicated above, the function works fine.

 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/

When I changed 100 from 1000, he solved the error, but I don’t understand why this happened in the first place?

+7
javascript jquery floating-point-precision
source share
4 answers

You can simply switch to this:

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

The working version of your jsFiddle: https://jsfiddle.net/jfriend00/5rLL04Lk/


Or, if you want to get around some of the features of .toFixed() , you can use this:

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

JsFiddle work: https://jsfiddle.net/jfriend00/xx2aj2L0/

This solution conveys all three of your test cases.

+1
source share

It is not Math.floor() that causes the problem, it is the inaccuracy of floating point arithmetic. When you multiply 8192.8 by 100 , you get 819279.9999999999 .

Perhaps you should just manipulate it as a string:

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

jsfiddle

+1
source share

The order of your gender / parsing seems to me out of order.

Try:

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

Although remember that 1.9999999999999999999999999999999999 gives 2.00, using the above; this is because floating point numbers cannot accurately represent all the values.

0
source share

another without using the Math function (2 lines without formatting)

 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]; } 
0
source share

All Articles