.toFixed()是否会导致计算错误?

时间:2019-02-09 22:17:50

标签: javascript

我正在创建一个简单的计算器,以显示进行找零所需的最少数量的硬币。用户输入改变量,并且该功能输出所需的四分之一,角钱,刻痕和便士数。除非百位数字(便士数字)为3或8,否则代码似乎正常工作。在这种情况下,它输出的便士比所需的少一分钱。在这种情况下,是否由于使用Math.ceil或toFixed而导致输出不正确?可以用什么代替?

我在显示非整数硬币的窗口中遇到问题,这就是为什么我开始使用Math.ceil()和toFixed()的原因。

function changeCalc() {
  let a = document.getElementById("changeTotal").value;
  let b = (a % 0.25).toFixed(2);
  let quartersNum = Math.ceil((a - b) / 0.25);
  if (b > 0) {
    var c = (b % 0.1).toFixed(2);
    var dimesNum = Math.ceil((b - c) / 0.1);
    if (c > 0) {
      var d = (c % 0.05).toFixed(2);
      var nicklesNum = Math.ceil((c - d) / 0.05);
      if (d > 0) {
        var e = (d % 0.01).toFixed(2);
        var penniesNum = Math.ceil((d - e) / 0.01);
        document.getElementById("changeWindow").innerHTML =
          `${quartersNum} quarters, ${dimesNum} dimes, ${nicklesNum} nickles, 
            ${penniesNum} pennies`;
      } else {
        document.getElementById("changeWindow").innerHTML =
          `${quartersNum} quarters, ${dimesNum} dimes, ${nicklesNum} 
               nickles`;
      }
    } else {
      document.getElementById("changeWindow").innerHTML =
        `${quartersNum} quarters, ${dimesNum} dimes`;
    }
  } else {
    document.getElementById("changeWindow").innerHTML =
      `${quartersNum} quarters`;
  }
}

例如,当我输入.18作为更改值时,我期望输出为0个季度,1个角钱,1个镍币和3个便士。而是输出0个季度,1个角钱,1个镍和2个便士。

2 个答案:

答案 0 :(得分:0)

是的。

在您的情况下:每次d = 0.03时,e都将为0.01,因为(0.03%0.01)将被计算为0.009999999999999998,这将由.toFixed(2)得出t0 0.01。

但是对于您的问题,如果您进行更改,则可以解决

if (d > 0) {
   var e = (d % 0.01).toFixed(2);
   var penniesNum = Math.ceil((d - e) / 0.01);

if (d > 0) {
   var penniesNum = Math.ceil((d) / 0.01);

希望这对您有所帮助。

答案 1 :(得分:0)

这不是toFixed()ceil()的问题,更确切地说是Floating-Point Imprecision的问题,尤其是javascript的问题。

有很多解决方法,但是对于您的问题,通常可以通过使用不必处理浮点数的解决方案来解决,例如将初始数字乘以100得到18,那么您完全可以避免该问题。

function changeCalc(inputString) {
  let a = parseInt(inputString * 100);
  let b = a % 25;
  let quartersNum = Math.floor(a / 25);
  if (b > 0) {
    var c = b % 10;
    var dimesNum = Math.floor(b / 10);
    if (c > 0) {
      var d = c % 5;
      var nicklesNum = Math.floor(c / 5);
      if (d > 0) {
        var penniesNum = d;
        console.log(
          `${quartersNum} quarters, ${dimesNum} dimes, ${nicklesNum} nickles, 
        ${penniesNum} pennies`);
      } else {
        console.log(
          `${quartersNum} quarters, ${dimesNum} dimes, ${nicklesNum} 
           nickles`);
      }
    } else {
      console.log(
        `${quartersNum} quarters, ${dimesNum} dimes`);
    }
  } else {
    console.log(
      `${quartersNum} quarters`);
  }
}

console.log("$0.18 is:");
changeCalc("0.18");

console.log("$0.24 is:");
changeCalc("0.24");

console.log("$0.33 is:");
changeCalc("0.33");