`

关于java,js数字计算丢失精度问题解析及解决方法

阅读更多

1.问题背景

 在用java计算金额时,使用double计算会出现精度丢失问题,用js直接加减乘除也会导致精度丢失。

2.问题解析

是什么导致java和js数字计算时精度丢失?引用孙卫琴的《Java面向对象编程》的内容来解释,由于计算机的二进制计算只能精确表示整数部分,无法精确表示小数部分,计算小数会产生精度丢失:

 

 

 

3.解决方案

java语言计算金额等需要精确数字时,可以使用java类库中的java.math.BigDecimal。而js计算时可以把数字转为整数计算即可。代码如下:

 /*

 * 加法运算,避免数据相加小数点后产生多位数和计算精度损失。
 *  
 * @param num1加数1 | num2加数2
 */
function numAdd(num1, num2) {
	var baseNum, baseNum1, baseNum2;
	try {
		baseNum1 = num1.toString().split(".")[1].length;
	} catch (e) {
		baseNum1 = 0;
	}
	try {
		baseNum2 = num2.toString().split(".")[1].length;
	} catch (e) {
		baseNum2 = 0;
	}
	baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
	return (num1 * baseNum + num2 * baseNum) / baseNum;
};
/**
 * 减法运算,避免数据相减小数点后产生多位数和计算精度损失。
 * 
 * @param num1被减数  |  num2减数
 */
function numSub(num1, num2) {
	var baseNum, baseNum1, baseNum2;
	var precision;// 精度
	try {
		baseNum1 = num1.toString().split(".")[1].length;
	} catch (e) {
		baseNum1 = 0;
	}
	try {
		baseNum2 = num2.toString().split(".")[1].length;
	} catch (e) {
		baseNum2 = 0;
	}
	baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
	precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;
	return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
};
/**
 * 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失。
 * 
 * @param num1被乘数 | num2乘数
 */
function numMulti(num1, num2) {
	var baseNum = 0;
	try {
		baseNum += num1.toString().split(".")[1].length;
	} catch (e) {
	}
	try {
		baseNum += num2.toString().split(".")[1].length;
	} catch (e) {
	}
	return Number(num1.toString().replace(".", "")) * Number(num2.toString().replace(".", "")) / Math.pow(10, baseNum);
};
/**
 * 除法运算,避免数据相除小数点后产生多位数和计算精度损失。
 * 
 * @param num1被除数 | num2除数
 */
function numDiv(num1, num2) {
	var baseNum1 = 0, baseNum2 = 0;
	var baseNum3, baseNum4;
	try {
		baseNum1 = num1.toString().split(".")[1].length;
	} catch (e) {
		baseNum1 = 0;
	}
	try {
		baseNum2 = num2.toString().split(".")[1].length;
	} catch (e) {
		baseNum2 = 0;
	}
	with (Math) {
		baseNum3 = Number(num1.toString().replace(".", ""));
		baseNum4 = Number(num2.toString().replace(".", ""));
		return (baseNum3 / baseNum4) * pow(10, baseNum2 - baseNum1);
	}
};

 遇到toFixed计算错误的问题,记录下。

Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法

http://www.jb51.net/article/121777.htm

 

分享到:
评论

相关推荐

    Java Double 精度问题总结

    #### 四、JavaScript 中的精度问题及解决方法 除了Java之外,在JavaScript中也会遇到类似的精度问题。一种常见的解决方案是使用 `Math.round` 函数来四舍五入结果。 ```javascript function formatFloat(src, pos)...

    浅谈java对象转json,数字精确出现丢失问题

    总的来说,Java对象转JSON过程中遇到的大数字精度丢失和科学记数法显示问题,主要是JavaScript引擎的限制所导致。通过将数字类型转换为字符串类型,可以有效地解决这个问题。在实际开发中,确保对大数字的处理方式有...

    完美解决方案-雪花算法ID到前端之后精度丢失问题.docx

    雪花算法ID到前端之后精度丢失问题解决方案 在本文中,我们将讨论雪花算法ID到前端之后精度丢失问题的解决方案。该问题是由于JavaScript中的Number类型精度限制所导致的。 一、问题描述 在一个项目中,我们使用...

    JS长整型精度问题实例分析

    JavaScript中的长整型精度问题是一个常见的困扰开发者的问题,特别是在涉及到大量数字操作或者与后端交互时。在JavaScript中,所有数字都是以浮点数的形式存储的,即使它们看起来像是整数。这种数据类型的设计限制了...

    json字符串转数组超过17位的数字 超过部分会被自动解析为0,造成数据错误.pdf

    为了解决这一问题,开发者采取了一种巧妙的方法:利用正则表达式将可能引起精度问题的数字转换为字符串类型,避免了数字类型转换时的精度损失。具体步骤如下: 1. **基本解决方案**:使用正则表达式将所有的数字...

    16进制单精度(32位)浮点型转换器源码

    对于Java开发者来说,这个转换器可能会使用Java的`java.nio.ByteBuffer`类来处理字节顺序,以及`Float.intBitsToFloat()`方法来完成从整数到浮点数的转换。此外,源码可能还包含错误检查和用户界面部分,以确保输入...

    json-java对象转换包

    - 转换过程中可能需要处理数据类型的不匹配问题,例如JSON中的数字可能会丢失精度。 - JSON不支持Java中的null值,转换时需注意处理。 综上所述,json-lib库在Java开发中起到了关键作用,它简化了JSON与Java对象...

    《JAVA程序设计》理论考题.doc

    (浮点数直接赋值给double类型)都是不合法的,因为存在精度丢失问题。 7. **Java源代码编译命令**:使用javac命令来编译Java源代码,所以选项A是正确的。 8. **编译后生成的文件扩展名**:Java源代码编译后生成的...

    java基础300多题.doc

    Java 基础300多题涉及到Java编程语言的核心概念和重要知识点,涵盖了Core Java、Hibernate、JavaScript和Servlet等多个领域。以下是对其中几个关键点的详细解释: 1. **面向对象的特征**: - **抽象**:抽象是将...

    初级java程序员笔试题.docx

    【Java 面试题解析】 一、判断题 1. 正确。Java 语言是一种面向对象的编程语言,它支持类、对象、封装、继承和多态等面向对象特性。 2. 错误。Java 的布尔类型是 `boolean`,只有 `true` 和 `false` 两个值,而...

    GRIB2 数据 转 JSON

    值得注意的是,由于GRIB2的复杂性,转换过程可能会丢失一些元数据或精度信息。因此,在实际使用时,应确保转换后的JSON数据能满足你的具体需求。如果遇到问题,可以查阅工具的文档(可能包括中文和英文版本),或者...

    BigNumber-源码.rar

    为了解决这个问题,Java提供了一个名为`BigDecimal`的类,它是`java.math`包下的一个核心类,专门用于进行精确的大数运算。`BigDecimal`是基于Java的大数运算库,它提供了丰富的操作方法,能够保证在执行加减乘除等...

    2021-2022计算机二级等级考试试题及答案No.10922.docx

    24. InputStream类方法:InputStream是Java中的一个基础输入流类,提供如`read(byte[])`这样的方法用于读取字节数据。 以上知识点涵盖了计算机系统的基础、软件开发、数据库管理和Web应用等多个领域,是计算机二级...

    2021-2022计算机二级等级考试试题及答案No.17753.docx

    6. 计算机性能:计算机运算速度快、精度高,能同时进行数值计算和逻辑运算,这是计算机的基本特性。 7. 数据单位:比特(Bit)是计算机能处理的最小数据单位,表示二进制的一位。 8. 创建数据库:通过“文件”菜单...

    2021-2022计算机二级等级考试试题及答案No.2160.docx

    - **解析**:在Java中,线程可以通过调用`notify()`方法来唤醒一个正在等待的对象锁的线程,使其从等待状态变为就绪状态。一旦线程获得了对象锁,就可以继续执行。需要注意的是,调用`notify()`方法并不会立即让线程...

    2021-2022计算机二级等级考试试题及答案No.5554.docx

    `abstract final double hyperbolicCosine( )`是合法的Java方法声明,表示一个抽象的、最终的双精度浮点数方法。 2. **数据库映像**:定义数据库全局逻辑结构与存储结构之间对应关系的是模式/内模式映像,这是...

    2021-2022计算机二级等级考试试题及答案No.16885.docx

    - **精度与小数位数:** 精度是指整个数字的位数,小数位数是指小数点后的位数。 - **数据类型选择:** 选择合适的数据类型可以有效地利用存储空间并提高查询性能。 ### 16. C 语言表达式求值 **题目描述:** 给出...

    2021-2022计算机二级等级考试试题及答案No.2423.docx

    ### 计算机二级等级考试知识点解析 #### 1. Word文档分栏功能 - **知识点**: Word文档支持分栏布局,允许用户自定义不同栏的宽度,这意味着可以在同一页中设置不同宽度的多栏布局。 #### 2. HTML文档中的注释符号 ...

    实验3 Java的基本数据类型和流程控制结构.doc

    - 显式转换:需要使用强制类型转换,如`(int)floatValue`,但可能丢失精度或溢出。 3. **流程控制结构**: - **If-else结构**:用于根据条件执行不同的代码块。 - **While结构**:当条件满足时,重复执行一段...

    2021-2022计算机二级等级考试试题及答案No.12071.docx

    ### 计算机二级等级考试知识点解析 #### 1. 主窗体和子窗体的链接字段 - **知识点解析**:在数据库设计中,主窗体和子窗体是常见的布局方式,用于展示和操作两个相关表或查询的数据。主窗体通常展示汇总信息或导航...

Global site tag (gtag.js) - Google Analytics