我在下面的场景中遇到了javascript的Math.floor函数的问题:
1)来自8192和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
奇怪的是,除了上面给出的范围外,该功能运行正常。
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/
当我用1000改变100时它解决了错误,但我不明白为什么这发生在第一个地方?
答案 0 :(得分:1)
您可以切换到:
return parseFloat(_self.userInput()).toFixed(2);
jsFiddle的工作版本:https://jsfiddle.net/jfriend00/5rLL04Lk/
或者,如果你想解决.toFixed()
的某些特性,你可以使用它:
return (Math.round(_self.userInput() * 100) / 100).toFixed(2);
工作jsFiddle:https://jsfiddle.net/jfriend00/xx2aj2L0/
此解决方案通过了所有三个测试用例。
答案 1 :(得分:1)
导致问题的不是Math.floor()
,而是浮点运算的不精确性。将8192.8
乘以100
后,您会获得819279.9999999999
。
也许您应该将其作为字符串进行操作:
function floorString(str) {
var pos = str.indexOf('.');
return (pos >= 0) ? ((str + '00').slice(0, pos + 3)) : (str + '.00');
}
答案 2 :(得分:0)
您的发言/解析顺序似乎不合适。
尝试:
return Math.floor(parseFloat(_self.userInput())).toFixed(2);
虽然知道1.999999999999999999999999999999使用上述2.00给出;这是因为浮点数不能精确地表示所有值。
答案 3 :(得分:0)
另一个没有使用Math
功能(没有格式化的2行)
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];
}