javaScript中Float精度计算

2023-10-26

    在项目中做了一个计算统计值的部分,实现过程是通过 javaScript 进行累加的。在测试时出现了一个很乖的问题,在此记录一下。


1. 问题背景

项目中有一个表格字段,数据类型是float的,在数据库中均以Decimal(10,2)的格式保存(也即有效数字为10,小数点为两位)。现在,要对该字段进行累加统计。

2. JavaScript实现

考虑到JavaScript中的数据是无类型的自动判断,因此没有多想,直接将这个字段循环累加,代码如下:

// 统计UFP值
RequireCount.prototype.addUFP = function(value) {
	this.count_ufp += value;
};
// 统计US总值
RequireCount.prototype.addUS = function(value) {
	this.count_US += value;
};


本以为很简单,但是在显示计算结果时,出现了让我感到纳闷的一幕:

未找到图片

    数据库中的数据全部都是小数点为两位的数据,怎么会出现这么长的小数点位数(50.68000000000001),也不该出现.00000000001吧?

3. 查找资料

    在JavaScript中,数值(浮点型)数据在存储时并不区分Number还是Float型,而是全部按照Float的类型来进行存储。存储方式为:整形部分的长度为10,小数部分位数为16;如果最后一位小数为0则用1代替(这个地方很难理解,为啥用1代替最后一位,具体解释是用1来代替有效数字位数)

4. 问题解释

    在统计过程中,如果出现了两者相加出现整数(也即后面小数点部分都满整了,比如,3.45 + 2.55 = 6.00),这时,计算结果将代替为:6.0000000000000001而不是,6.00。因为根据以上资料的规定就是这么个意思。是不是很奇怪的规定惊讶惊讶惊讶,不知道为什么这么规定,需要以后深入了解。

5. 解决方式(根据目前情况,并非正确解决方案,请勿模仿偷笑

因为,项目中的数据量不是很大,按照精度问题来说,后面的一大片零头不会影响前面的数据结果,故而使用了 toFixed方法截取所需要的部分:

<span style="font-size:18px;">var floatTest = 5.6849392174

var needFloat = loatTest.toFixed(2)</span>
虽然,不是正确的解决方案,但是针对目前情况来讲,是一个适用的“解决方案”安静

6. 问题延展及终极解决方案

加法会出现此问题,我们自然就会想到减法运算,然后就是乘除运算。

对于乘法,这不能这么“大意大胆”的使用上面的方式,毕竟乘法可不是一点点的累加了,可以说是:失之毫厘谬以千里啊。

6.1 加法:

function add(value1, value2) {
	var r1, r2, m;
	try {
		r1 = value1.toString().split(".")[1].length;
	} catch (e) {
		r1 = 0;
	}
	try {
		r2 = value2.toString().split(".")[1].length;
	} catch (e) {
		r2 = 0;
	}
	m = Math.pow(10, Math.max(r1, r2));
	return (value1 * m + value2 * m) / m;
}

6.2 减法:

function Subtr(value1, value2) {
	var r1, r2, m, n;
	try {
		r1 = value1.toString().split(".")[1].length;
	} catch (e) {
		r1 = 0;
	}
	try {
		r2 = value2.toString().split(".")[1].length;
	} catch (e) {
		r2 = 0;
	}
	m = Math.pow(10, Math.max(r1, r2));
	// 动态控制精度长度
	n = (r1 >= r2) ? r1 : r2;
	return ((value1 * m - value2 * m) / m).toFixed(n);
}


6.3 乘法:

function multiple(value1, value2) {
	var m = 0, s1 = value1.toString(), s2 = value2.toString();
	try {
		m += s1.split(".")[1].length;
	} catch (e) {
	}
	try {
		m += s2.split(".")[1].length;
	} catch (e) {
	}
	return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}


6.4 除法:

function divider(value1, value2) {
	var t1 = 0, t2 = 0, r1, r2;
	try {
		t1 = value1.toString().split(".")[1].length;
	} catch (e) {
	}
	try {
		t2 = value2.toString().split(".")[1].length;
	} catch (e) {
	}
	with (Math) {
		r1 = Number(value1.toString().replace(".", ""));
		r2 = Number(value2.toString().replace(".", ""));
		return (r1 / r2) * pow(10, t2 - t1);
	}
}




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

javaScript中Float精度计算 的相关文章

随机推荐

  • 5折交叉验证的回归分析

    w lt read csv C Users Administrator Desktop mg csv header T 样本的个数为1385 5折交叉验证 n 1385 zz1 1 n zz2 rep 1 5 ceiling 1385 5
  • PTA 7-15 计算圆周率 (15 分)

    根据下面关系式 求圆周率的值 直到最后一项的值小于给定阈值 2 1 31 3 52 3 5 73 3 5 7 2n 1 n 输入格式 输入在一行中给出小于1的阈值 输出格式 在一行中输出满足阈值条件的近似圆周率 输出到小数点后6位 输入样例
  • 音视频基础(1)音视频处理流程

    文章目录 音视频基础 1 音视频处理流程 1 概要 2 音频处理流程 3 视频处理流程 4 直播客户端处理流程 5 音频数据流转 音视频基础 1 音视频处理流程 理解音频处理流程对我们做音视频开发至关重要 因为理解了这个处理流程之后 我们就
  • mysql用户授权

    mysql用户授权 1 grant授权 授权 添加用户并设置权限 命令格式 grant 权限列表 on 库名 表名 to 用户名 客户端地址 identified by 密码 with grant option with grant opt
  • draw.io环境搭建

    为什么80 的码农都做不了架构师 gt gt gt 前言 draw io是一款在github上的开源产品 由于需要构建在线文档 需要插入画图类型 对比多款开源产品 最终选择了draw io draw io图标资源非常的丰富 方便导入图标资源
  • Android——(高级控件下拉框与搜索框)

    1 高级控件与低级控件区别 是否使用适配器 2 适配器种类和作用 2 1 种类 数组适配器 ArrayAdapter new ArrayAdapter
  • MySQL - java链接mysql8 并兼容链接mysql5 亲测可用

    开始之前先去官网捋一遍 MySQL Connector J开发人员指南 看看官方的一些变动 和一些可能要注意的点 或者一些可能会踩到的坑 事先 我们要有一个使用mysql5 x的应用或者服务 需要修改的部分不算多 但是要想同时想兼容5 x和
  • java: cannot find symbol symbol: variable log

    使用Intellij idea的时候 编译项目始终报错java cannot find symbol symbol variable log 装Lombok Plugin 插件 设置 build execution deployment g
  • react-redux库

    安装react redux tnpm i react redux 未优化前 src components Count index tsx import React useState from react export default fun
  • UE4命令行打包项目

    RunUAT bat在ue安装路径找 1 Compiling the client 编译客户端的命令行代码 RunUAT BuildCookRun project full project path and project name upr
  • MySQL 命令环境变量设置方法

    安装完MySQL之后 大家可以直接打开MySQL的client输入命令 操作MySQL数据库 当然也可以使用dos窗口输入MySQL命令操作MySQL数据库 方法1 1 打开dos窗口 具体怎么打开 百度 2 定位到MySQL安装目录下的b
  • jmeter生成随机数

    打开函数助手 Random 写入随机范围的最小值 和最大值 name of variable in which to store the result 为变量名 写好后 点击生成 复制字符串 粘贴到需要的请求上即可
  • linux查看vlan命令,[转]linux VLAN配置(vconfig)

    1 安装vlan vconfig 和加载8021q模块 aptitude install vlan modprobe 8021q 2 使用linux vconfig命令配置vlan vconfig add eth0 100 vconfig
  • 网络安全——cobalt Strike 之office钓鱼

    一 office钓鱼 在无需交互 用户无感知的情况下 执行office文档中内嵌的恶意代码 例如宏 从远控地址中下载并运行恶意可执行程序 例如远控木马 勒索病毒等 cobalt strike office钓鱼原理 主要生成一段vba代码 然
  • 前端发送的form-data类型name=“carNumber“的参数后端怎么接收

    需求 前端将图片和其他信息一起已form data类型发送给后端 图片以二进制流的形式 其他信息以key value的键值对的形式 举例 具体荷载 后端controller层接收的方法 RequestMapping value upload
  • linux安装jdk8

    1 官网下载链接 Java Downloads Oracle 2 下载完成之后 我们打开linux 执行如下命令 最后通过rz命令将文件上传 root localhost local mkdir usr local java root lo
  • android imageloader 进度条,Android-Universal-Image-Loader使用介绍

    图片开源库是一个应用非常广泛的第三方库 几乎所有的应用都会使用 目前而言常见的图片库有 Android Universal Image Loader Picasso Fresco Glide等 下面是国内Top500Android应用分析报
  • Win10笔记本屏幕最低亮度依旧很亮?最高亮度依旧很暗?

    左下角搜索 显卡 打开 英特尔R显卡控制中心 点击 显示器 点击 颜色 里面有 全部颜色 在这里调节即可 嫌太亮 调低些 反之则反
  • 必刷算法题之排序篇(题目及代码)---C++

    前言 该篇博客记录了和排序有关的一些题目 差不多是逐级递增的难度 后续还会补充 有具体思路和代码 文章目录 第一题 排序 第二题 判断字符是否唯一 第三题 最小的k个数 第四题 单链表的排序 第五题 最大数 第六题 调整数组顺序使奇数位于偶
  • javaScript中Float精度计算

    在项目中做了一个计算统计值的部分 实现过程是通过 javaScript 进行累加的 在测试时出现了一个很乖的问题 在此记录一下 1 问题背景 项目中有一个表格字段 数据类型是float的 在数据库中均以Decimal 10 2 的格式保存