《JavaScript入门经典(第4版)》上第5章一个实例程序的修正,完善

 

今日,做《JavaScript入门经典(第4版)》第5章上的一个例题,感觉书上的代码有个小错误。

这是ch5_examp5.html上的一个实例,是计算一个数x保留y小数位后,四舍五入的结果是什么。

代码如下:

   1:  <script type="text/javascript">
   2:   
   3:  function fix(fixNumber, decimalPlaces)
   4:  {
   5:      var div = Math.pow(10,decimalPlaces);
   6:      fixNumber = Math.round(fixNumber * div) / div;
   7:      return fixNumber;
   8:  }
   9:  </script>
  10:  </head>
  11:  <body>
  12:  <script type="text/javascript">
  13:   
  14:  var number1 = prompt("Enter the number with decimal places you want to fix","");
  15:  var number2 = prompt("How many decimal places do you want?","");
  16:   
  17:  document.write(number1 + " fixed to " + number2 + " decimal places is: ");
  18:  document.write(fix(number1,number2));
  19:   
  20:  </script>

 

但这个代码运行后有个问题,就是如果输入1.995,要求保留2个小数位,但结果却是“2”,原因在于在用pow()方法乘以原数字并用Math.round()方法后,这样的情况会出现尾数为“0”的情况,再除以10,100这样的,就不能保留我们希望保留的小数位了。

因此,书上的代码是有问题,我捉摸了一下,可以对原有代码做个修正,加一个if判断,如果尾数为0,则说明这种情况出现了,需要进行修正。新的代码如下:

 

   1: <script type = "text/javascript">
   2:             function deci(x,y){
   3:                 var a = x*(Math.pow(10,y));
   4:                 x = (Math.round(a)) / (Math.pow(10,y));
   5:                 var z = new String(Math.round(a)); // 创建一个新变量z,将Math.round(a)转为字符串类型,这样就可以用charAt方法判断字符串的最后一位是否为0)
   6:                 if (z.charAt(z.length-1) ==0) //如果变量z的最后一位为0,则说明除以10*y后,会变成整数,不保留小数位,所以要用toFixed方法强制保留小数位;
   7:                      {
   8:                      var u = new Number(x); //创建一个新变量u,将x转为Number类型,这样就可以调用toFixed方法
   9:                      var t = u.toFixed(y);  //创建一个新变量t,将u取小数位y位;
  10:                      return t;
  11:                      }
  12:                 else
  13:                 return x;
  14:             }
  15:             var X1 = prompt("please input x", "");
  16:             var Y1 = prompt("please input y","");
  17:             
  18:             document.write(deci(X1,Y1));
  19:         </script>

 

这个解决方案比较复杂,需要先创建一个新变量z,将原数据变量类型转为字符串,才好使用charAt方法去获取最后一个字符值(我试了,charAt方法,只能用于字符串类型),然后进行条件判断,如果变量z最后一位是0,则需要将变量x先转为Number类型,再使用toFixed方法,强制赋予y位的小数位。

但这个解决方案,也不是很好,简单的问题,搞得这么复杂,中间涉及大量数据转换乃至数据类型转换,如果不是为了学知识,仅是从算法而言,是在不符合“简单为美”的原则。后来想到既然将简单数值型变量,用new Number方法转为Number对象后,就可以使用toFixed()方法了,为何还要使用pow()方法+round()方法的方式去处理?可以直接转换成Number对象再强制保留小数位即可。代码优化后如下,执行结果完全无问题。

 

   1: <script type = "text/javascript">
   2:             function deci(x,y){
   3:                 var a = new Number(x); //将变量x转换为Number对象类型,这样就可以使用toFixed()方法了
   4:                 var b = a.toFixed(y);  //toFixed()方法,可以实现按规定小数位四舍五入
   5:                 return b; 
   6:             }
   7:             var X1 = prompt("please input x", "");
   8:             var Y1 = prompt("please input y","");
   9:             
  10:             document.write(deci(X1,Y1));
  11:         </script>
posted on 2011-11-23 09:22  CDDF  阅读(318)  评论(0编辑  收藏  举报