float、double精度可能丢失,decimal精度不会丢失,所以建议decimal来存储金额值。
在mysql中,我们用【小数数据类型(总长度,小数点长度)】来表示小数的总长度和小数点后面的长度。decimal(m,n)。n就是小数点后面的 数字个数。float(m,n)、double(m,n)含义差不多,都是定义长度和精度的。
下面看实操演示
1 2 3 4 5 | -- total_price精度为小数点后六位<br>CREATE TABLE `order` ( `id` bigint (11) NOT NULL , `total_price` float (10,6) NOT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;<br><br> -- insert<br>INSERT INTO `co_job`.`order`(`total_price`) VALUES (32.214);<br><br>-- query<br>SELECT * FROM `order` WHERE `id` = 1; |

1 | <br><br> |
第一种情况: 存入小数精度不够6位
那么mysql会尽可能以近似的值存储,以保证精度。这里会出现精度丢失
第二种情况: 存入小数精度刚好6位
1 | INSERT INTO ` order `(`total_price`) VALUES (32.214412); SELECT * FROM ` order ` WHERE `id` = 2;<br><br> |

仍然发生了精度丢失。
在查阅资料可知,单精度类型float和双精度类型double在计算机中存储的时候,由于计算机只能存储二进制,所以浮点型数据在存储的时候,必须转化成二进制。在计算机中,float型数据的存储格式为
比如8.25用二进制表示可表示为1000.01,转成指数的形式1.00001*2^3,在计算机中
我们知道对于float类型的数据,只分配了32位的存储空间,对于double类型值分配了64位,但是并不是所有的实数都能转成32位或者64位的二进制形式,如果超过了,就会出现截断,这就是误差的来源。
比如131072.32转成二进制后的数据为:100000000000000000.0101000111101011100001010001111010111000010100011111… 这是一个无穷数,对于float类型,只能截取前32位进行存储,对于double只能截取前64位进行存储。所以 131072.32保存为float类型是存储形式为:01001000000000000000000000010100; 131072.32保存为double类型的格式为:0100000100000000000000000000001010001111010111000010100011110101
针对float情况,至少我们可以得出结论:
1.如果一个float型数据转成二进制后的第32位之后都是0,那么数据是准的
2.如果一个float型数据转成二进制后的第32位之后不全为0,则数据就会存在误差
第三种情况:存入小数精度大于6位
这种情况不必多说,一定会出现精度丢失。
参考资料:https://cloud.tencent.com/developer/article/1866266
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具