Java和MySQL数据库中关于小数的保存问题详析
前言
之前总结过一篇文章mysql数据库decimal类型与decimal长度用法详解,主要是个人学习期间遇到的mysql中关于decimal字段的详解,最近在群里遇到一个小伙伴提出的问题,也有部分涉及,今天就再大致总结一下Java和MySQL数据库中关于小数的保存问题
Java 中的小数类型
在Java中,小数的表示主要依赖于两个基本数据类型:float和double。这两种类型都是浮点类型,但它们在精度和存储空间上有所不同。
float
单精度浮点数,字节数为 4,占用32位,整数部分最多 7 位,小数部分最多 7 位,取值范围太小,几乎没有用,但通常用于节省内存空间。
double
双精度浮点数,字节数为 8,占用64位,整数部分最多 15 位,小数部分最多 15 位,基本够用,计算金钱可以达到1 亿亿以内的范围;提供更高的精度,但占用更多的内存空间。
BigDecimal
比较大的小数只能使用 BigDecimal 来接收,MySQL 数据库 decimal 可以保存最多 65 位的小数,但是 double只能接收差不多 15 位的小数。
数据库获取到数据需要转换成字符串类型,然后再使用 BigDecimal(String) 构造器将数值封装成一个 BigDecimal 对象。
在实际开发中,选择合适的类型要根据精度和内存占用的平衡,以满足业务需求。
MySQL 中的小数类型
MySQL中提供了多种小数类型,主要包括FLOAT、DOUBLE、DECIMAL。每种类型都有其独特的特点。
1. FLOAT
单精度浮点数,适用于需要较大范围的数值,但对精度要求不高的情况。
用于表示近似数值数据类型。SQL 标准允许在关键字 float 后面的括号内选择用位指定精度(但不能为指数范围)。0 到 23 的精度对应 float 列的 4 字节单精度。
myfloat FLOAT(8,4);
例如上面,定义为 float(8,4) 的一个列可以显示为 -9999.9999。MySQL 保存值时进行四舍五入,因此如果在 float(8,4) 列内插入 9990.00009,近似结果是 9990.0001。
⚠️:float 数据在运算时,如果数字溢出不会报错,会有精度的损失。
2. DOUBLE
双精度浮点数,提供更高的精度,适用于对数值精度要求较高的场景。
可以设置保留的小数个数。decimal(m,d),表示该值一共显示 m 位整数,其中 d 位位于小数点后面。
decimal 和 numeric 类型在 MySQL 中视为相同的类型。它们用于保存必须为确切精度的值,例如货币数据。当声明该类型的列时,可以(并且通常要)指定精度和标度。
例如:
salary decimal(5,2)
在该例子中,5 是精度,2 是标度。精度表示保存值的主要位数,标度表示小数点后面可以保存的位数。
在标准SQL中,语法 decimal(m) 等价于 decimal(m,0)。同样,语法 decimal 等价于vdecimal(m,0),可以通过计算确定 m 的值。在MySQL 5.1中支持 decimal 和 numeric 数据类型的变量形式。m 默认值是 10。
decimal 或 numeric 的最大位数是 65,但具体的 decimal 或 numeric
列的实际范围受具体列的精度或标度约束。如果此类列分配的值小数点后面的位数超过指定的标度允许的范围,值被转换为该标度。(具体操作与操作系统有关,但一般结果均被截取到允许的位数)。
注:当对 decimal 类型的数据进行运算操作时,如果数值溢出会报错。
3.Float
单精度浮点数,适用于需要较大范围的数值,但对精度要求不高的情况。用于表示近似数值数据类型。
SQL 标准允许在关键字 float后面的括号内选择用位指定精度(但不能为指数范围)。0 到 23 的精度对应 float 列的 4 字节单精度。
例如,定义为 float(7,4) 的一个列可以显示为 -999.9999。MySQL 保存值时进行四舍五入,因此如果在 float(7,4) 列内插入 999.00009,近似结果是 999.0001。
注:float 数据在运算时,如果数字溢出不会报错,会有精度的损失。
对比分析
1. 精度要求
- 如果业务对小数的精度要求较低,且对内存占用有要求,可以选择使用float。
- 如果需要更高的精度,但仍然可以容忍一定的舍入误差,可以选择使用double。
- 如果业务对小数的精度要求非常高,且不能容忍任何误差,应该选择DECIMAL。
2. 存储空间
- float占用4字节,适用于存储较大范围的数值。
- double占用8字节,提供更高的精度,但占用更多的存储空间。
- DECIMAL的存储空间与精度有关,但通常比double更节省存储空间。
3. 舍入误差
- 浮点数(float和double)在进行计算时可能存在舍入误差,因为它们是基于二进制表示的,而十进制小数无法精确表示为二进制小数。
- DECIMAL类型是基于十进制的,不会出现浮点数的舍入误差,适用于对精度要求极高的场景。
总结
到此这篇关于Java和MySQL数据库中关于小数的保存问题的文章就介绍到这了,更多相关Java和MySQL中小数保存问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
java 用redisTemplate 的 Operations存取list集合操作
这篇文章主要介绍了java 用redisTemplate 的 Operations存取list集合操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-08-08Java 添加、删除、替换、格式化Word中的文本的步骤详解(基于Spire.Cloud.SDK for Java)
这篇文章主要介绍了Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java),本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-08-08解决java.lang.NoClassDefFoundError:lombok/Data报错问题
在Java开发中,使用Lombok库简化代码非常普遍,今天在启动拉取的git代码时,遇到了java.lang.NoClassDefFoundError:lombok/Data的报错,经过检查,发现错误的原因是将Date误写为Data,且错误地引用了lombok.Data包2024-09-09
最新评论