IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> toFixed() 踩坑----四舍六入 银行家算法 -> 正文阅读

[JavaScript知识库]toFixed() 踩坑----四舍六入 银行家算法

你绝对想不到 toFixed()明明是数字的方法,结果转出来的是字符串,转字符串也就算了,结果,值还有可能不对。
我们正常理解的四舍五入,及时见5就入。但是你看看
在这里插入图片描述
在这里插入图片描述
对比之下发现 不管是 数字类型的 1.45 还是1.35 在toFixed()后都是1.4,结果还是字符串。什么原因呢

其实这也不错,为啥----

银行家算法:四舍六入五考虑,五后非0 就进一,五后为0看奇偶,五前为偶当舍去,五后为奇要进一。

银行家算法是一种最有代表性的 避免死锁的算法。 在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。

例子如下。
在这里插入图片描述
所以这就造成了1.35 和1.45 在四舍五入后都是1.4 (银行家就是 5前奇进偶不进)

但是你看看toFixed(),假设总共有3块钱,我们用toFixed() 去分钱,结果就有问题。1.25和1.75 的时候就会多1毛前,如果在财务中,这1毛钱就翻天了。
在这里插入图片描述

好了继续说一下toFixed()(全TM是字符串),
toFixed它是一个四舍六入 五成双的诡异的方法(也叫银行家算法),
"四舍六入五成双"含义:对于位数很多的近似数,当有效位数确定后,其后面多余的数字应该舍去,只保留有效数字最末一位,这种修约(舍入)规则是“四舍六入五成双”,也即“4舍6入5凑偶”这里“四”是指≤4 时舍去,"六"是指≥6时进上,"五"指的是根据5后面的数字来定,当5后有数时,舍5入1;当5后无有效数字时,需要分两种情况来讲:①5前为奇数,舍5入1;②5前为偶数,舍5不进。(0是偶数)
但是
经过我的测试发现,在chorme下面(最新版),并没有完全遵守这个规则,尤其是5的后面没有数字的时候,不是这么判断的,如下:
继续先看例子 跟上边的测试例子有冲突

var b = 1.335
console.log(b.toFixed(2)) //	"1.33" 是不是以为是1.34

var b = 1.345
console.log(b.toFixed(2)) // 	"1.34" 是不是以为是1.35

var b = 1.355
console.log(b.toFixed(2)) //	"1.35" 是不是以为是1.36

var b = 1.365
console.log(b.toFixed(2)) //	"1.36" 是不是以为是1.37

var b = 1.375
console.log(b.toFixed(2)) // 	"1.38"

var b = 1.385
console.log(b.toFixed(2)) //	"1.39"

在这里插入图片描述
可以发现在chorme下没有完全去遵循这个规律,或许它有自己的算法,但是毕竟它没有遵循通用的银行家算法,所以

tofixed这个方法在涉及到金钱计算的业务中还是少用, 最好别用,否则可能会出大问题!

自己的做法就是根据 精确位数 来取小数点后的数,然后判断精确位是大于4还是小于等于4,上代码吧,不说了:

假设做做到 是两位小数,最少就是取整,不留小数

function moneySwitch(money, precision){ // precision是需要精确的位数,如百分位就是2
var result = 0;
//先进行一个千分位的四舍五入,保证3.0999这种情况在保留一位小数的时候能是对的,这一位可以这么做没什么问题
var money = parseFloat(money).toFixed(3);
try{
    var int_part = money.split(".")[0], // 小数点前的整数
    point_num = money.split(".")[1], // 取小数点后面的小数
    precision_num = point_num[3-precision];
    if(precision_num>4){//五入的情况
        if(precision==1){
            point_num = parseInt(point_num)+10+"";
            if(point_num.length>3){//说明往整数位进1
                int_part = parseInt(int_part)+1+"";
                point_num = point_num[1]+point_num[2];
            }else{
                point_num = point_num[0]+point_num[1];
            }
            result = parseFloat(int_part+"."+point_num);
        }else if(precision==2){
            point_num = parseInt(point_num)+100+"";
            if(point_num.length>3){//说明往整数位进1
                int_part = parseInt(int_part)+1+"";
                point_num = point_num[1];
            }else{
                point_num = point_num[0];
            }
            result = parseFloat(int_part+"."+point_num);
        }else if(precision==3){
            int_part = parseInt(int_part)+1+"";
            point_num = 0;
        }
        result = parseFloat(int_part+"."+point_num);
    }else{//四舍的情况
        if(precision==1){
            point_num = point_num[0]+point_num[1];
        }else if(precision==2){
            point_num = point_num[0];
        }else if(precision==3){
            point_num = 0;
        }
        result = parseFloat(int_part+"."+point_num);
    } 
}
catch(e){
    return parseFloat(money).toFixed(2);//如果过程中有出错就tofixed代替为解决
}
	return result;
}

真心用了toFixed()后坑死我了。

把toFixed() 转换成数字类型的方法

在这里插入图片描述
但是这些后期也会有问题。

推荐写法 Math.round(x) 函数返回一个数字四舍五入后最接近的整数。
Math.round( x * 100) / 100
在这里插入图片描述
但是发现这个只能是两位小数。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:14:27  更:2022-04-09 18:14:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:52:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码