js实现小数点四舍五入
js实现小数点四舍五入
其实这个问题,在之前的面试中被提问到了,由于笔者平时都是用原生的
toFixed()的方法来保留小数点,所以当时并没有回答出来这个问题,呜呜呜.
现在突然想起了这个问题,就研究一下吧。
最简单的实现方法
可以使用
Math对象的一些方法来实现,这个比较简单,主要用到了Math.round和一些简单的乘除法运算。例子
思路:
1. 先把数值转成只有一位小数点的数值
2. 利用Math.round方法四舍五入(关键)
3. 最后通过乘除法运算等到想要的小数点位数
function toFixed(num,decimal){
if(isNaN(num)){
return 0;
}
num = num-0;
var p1 = Math.pow(10, decimal + 1);
var p2 = Math.pow(10, decimal);
console.log(num * p1 / 10);
console.log(Math.round(num * p1 / 10));
return (Math.round(num * p1 / 10) / p2).toFixed(decimal); //思考一下,为什么要除10?
}
运行一下上面的代码,其实有隐藏的bug...
toFixed(2.555,2) //2.56
toFixed(4100.065,2) //4100.06 ???
console.log(4100065/10) //410006.49999999994 这就是bug的答案
0.1+0.2=? //0.30000000000000004
所谓的隐藏bug,就是js编程语言的小数点精度问题,所以上面那个除于10 只是在一定的范围内有效,过了这个范围,还是会出现精度问题...
用字符串处理
既然小数点进行运算会出现问题,那我们换一种思路,用字符串来处理。例子
思路:
1. 把数字转成字符串,然后把小数点移动到倒数第二位。(模拟只有一位小数点)
2. 还是用到Math.round来四舍五入
3. 重复第一个步骤,不过把小数点移动到(你要保留多少位小数点)
function toFixed(num,decimal){
if(isNaN(num)){
return 0;
}
var strnum = num+'';
var arr = strnum.split('.');
if(arr.length<2){
return num.toFixed(decimal);
}
strnum = arr.join('');
var strnum2 = strnum.slice(0,-1)+'.'+strnum.slice(-1);
var result = Math.round(strnum2-0)+'';
if(arr[1].length==decimal){
result+='0'; //如果小数点的个数刚好等于要保留的小数点个数,要补0
}
return result.slice(0,-decimal)+'.'+result.slice(-decimal)
}
2020-04 更新
上面的字符串处理不够好,下面补充个新的逻辑方式:
- 把数字转成字符,并记录
.小数点的位置;如果没有小数点,则直接在后面补0; - 通过小数点的位置,计算出原数字有多少位小数(oldPointNum);把小数点去掉并且把字符串转成数组;
- 通过比较oldPointNum和n(要保留的位数);如果oldPointNum<n,直接补0;否则下一步
- 比较数组倒数(i =oldPointNum-n)的数字是否>=5;是则进一位;i++;循环该步骤(核心),用这一步来模拟四舍五入。
const toFixed = (number, n) => {
let numberStr = number + "";
let reg = /^(-|\+)?(\d+(\.\d*)?|\.\d+)$/i;
if(!reg.test(numberStr)) {
console.error('输入的数字格式不对');
return;
}
let sign = numberStr.charAt(0) === '-' ? (numberStr=numberStr.slice(1),-1):1; // 判断是否是负数
let pointIndex = numberStr.indexOf("."); // 记录小数点的位置
if (pointIndex > -1) {
numberStr = numberStr.replace(".", "");
} else { // 没有小数点直接添加补0;
numberStr += ".";
numberStr+=new Array(n).join('0');
return numberStr;
}
let numberArray = numberStr.split(""); //转成数组
let len = numberArray.length;
let oldPointNum = len - pointIndex; // 获取原数据有多少位小数
if (oldPointNum < n) { // 要保留的小数点比原来的要大,直接补0
while (n - oldPointNum > 0) {
numberArray.push(0);
n--;
}
} else if (oldPointNum > n) { // 模拟四舍五入
let i = oldPointNum - n; // 从倒数第i个数字开始比较
let more = numberArray[len - i] >= 5 ? true : false;
while (more) {
i++;
more = +numberArray[len - i] + 1 === 10 ? true : false; // 进位后判断是否等于10,是则继续进位
numberArray[len - i] = more&&i!==(len+1) ? 0 : +numberArray[len - i] + 1; // 其他位置的数字进位直接变成0,第一位的例外
console.log(i, len);
}
numberArray.length = len- (oldPointNum-n); // 截取多余的小数
}
numberArray.splice(pointIndex, 0, ".");
return sign===-1?'-'+numberArray.join(""):numberArray.join("");
};
ps :上面的代码有点臃肿,其实可以通过正则来简化,以后有空修改。
js实现小数点四舍五入的更多相关文章
- JS保留小数点(四舍五入、四舍六入)实例
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- js 让小数四舍五入保留两位小数的函数是?
js 让小数四舍五入保留两位小数的函数是? 例子:data.relations[i].data[j].toFixed(2) toFixed(2)这个函数就是保留两位小数的作用
- java四舍五入BigDecimal和js保留小数点两位
java四舍五入BigDecimal保留两位小数的实现方法: // 四舍五入保留两位小数System.out.println("四舍五入取整:(3.856)=" + ne ...
- js判断小数点几位
js如何判断小数点后有几位 <script> var n=3.143423423;alert(n.toString().split(".")[1].length); & ...
- js保留小数点后面几位的方法
原文地址: http://www.jb51.net/article/45884.htm 四舍五入以下处理结果会四舍五入: ? 1 2 var num =2.446242342; num = num.t ...
- js 获取小数点位数方法及 字符串与数字之间相互转换方法
1.获取小数点位数方法 a. 使用 js 中 subsrting,indexOf,parseFloat三个函数,代码如下: var s = "22.127456" ;//s 为 字 ...
- js 小数[非]四舍五入
1.四舍五入 (2.678).toFixed(2) // 2.68 2.不需要四舍五入 (parseInt(2.678*100)/100.0).toFixed(2) // 2.67 3.字节单位转换 ...
- js数字格式化-四舍五入精简版
搜索网上的,数字格式化过余复杂,自己想了个简单方法,欢迎吐槽. 简化说明: '123333' => 12.3万 parseInt('123333') 字符串转整型 parseInt('12333 ...
- js 加减乘除以及四舍五入 新写法
1 四舍五入 eg: (1.23).round() = 1.2 (1.2456).round(3) = 1.246 Number.prototype.round = function (count) ...
随机推荐
- 【水滴石穿】react-native-video-project
感觉这个是很有才华的博主,毕竟是可以在npm 包里面留后门的程序员 博主的gihtub关于这个项目的地址是:https://github.com/ikimiler/react-native-video ...
- ubuntu上安装notepadpp
Notepad++是一套非常有特色的自由软件的纯文字编辑器(许可证:GPL).有完整的中文化接口及支持多国语言编写的功能(UTF8 技术).它的功能比 Windows 中的 Notepad(记事本)强 ...
- SpringBoot Cloud eureka 注册中心
SpringBoot Cloud是什么 Spring Cloud是一个分布式的整体解决方案. Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一 ...
- 转:国内从事CV相关的企业
http://blog.csdn.net/carson2005/article/details/7356225 经常碰到朋友问我国内从事计算机视觉(CV)领域的公司的发展情况,产品情况,甚至找工作等问 ...
- 关于JSP的淘汰问题(转)
来源:http://1t.click/peD 大中型公司需要专业人才,小公司需要全才,但是对于个人职业发展来说,我建议是分开.你要是这辈子就吃java这碗饭,就不要去研究什么css,js等等. 把你的 ...
- jQuery图片从下往上滚动效果
在线演示 本地下载
- 元素的高度(基于vue)
const viewH =el.target.offsetHeight;//可见高度 const contentH =el.target.scrollHeight;//内容高度 const scrol ...
- WPF自定义控件 依赖属性绑定
控件cs文件 using System.ComponentModel; using System.Windows; using System.Windows.Controls; using Syste ...
- Myeclipse自定义注释
1.设置模板 Windows—Preference—Java—Code Style—Code Templates 图中, Configure generated code and comments中的 ...
- c50决策树借款风险
Decision Trees/ Machine Learning Durga Gaddam August 29, 2016 Objective: The objective of the articl ...