《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>