在Java中,小数的表示主要依赖于两个基本数据类型:float和double。这两种类型都是浮点类型,但它们在精度和存储空间上有所不同。
单精度浮点数,字节数为 4,占用32位,整数部分最多 7 位,小数部分最多 7 位,取值范围太小,几乎没有用,但通常用于节省内存空间。
双精度浮点数,字节数为 8,占用64位,整数部分最多 15 位,小数部分最多 15 位,基本够用,计算金钱可以达到1 亿亿以内的范围;提供更高的精度,但占用更多的内存空间。
比较大的小数只能使用 BigDecimal 来接收,MySQL 数据库 decimal 可以保存最多 65 位的小数,但是 double只能接收差不多 15 位的小数。 数据库获取到数据需要转换成字符串类型,然后再使用 BigDecimal(String) 构造器将数值封装成一个 BigDecimal 对象。
在实际开发中,选择合适的类型要根据精度和内存占用的平衡,以满足业务需求。
MySQL中提供了多种小数类型,主要包括FLOAT、DOUBLE、DECIMAL。每种类型都有其独特的特点。
单精度浮点数,适用于需要较大范围的数值,但对精度要求不高的情况。 用于表示近似数值数据类型。SQL 标准允许在关键字 float 后面的括号内选择用位指定精度(但不能为指数范围)。0 到 23 的精度对应 float 列的 4 字节单精度。
myfloat FLOAT(8,4);例如上面,定义为 float(8,4) 的一个列可以显示为 -9999.9999。MySQL 保存值时进行四舍五入,因此如果在 float(8,4) 列内插入 9990.00009,近似结果是 9990.0001。
⚠️:float 数据在运算时,如果数字溢出不会报错,会有精度的损失。
双精度浮点数,提供更高的精度,适用于对数值精度要求较高的场景。 可以设置保留的小数个数。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 类型的数据进行运算操作时,如果数值溢出会报错。
单精度浮点数,适用于需要较大范围的数值,但对精度要求不高的情况。用于表示近似数值数据类型。 SQL 标准允许在关键字 float后面的括号内选择用位指定精度(但不能为指数范围)。0 到 23 的精度对应 float 列的 4 字节单精度。
例如,定义为 float(7,4) 的一个列可以显示为 -999.9999。MySQL 保存值时进行四舍五入,因此如果在 float(7,4) 列内插入 999.00009,近似结果是 999.0001。
注:float 数据在运算时,如果数字溢出不会报错,会有精度的损失。