mysql float 的坑谁遇到过

字段 类型 长度 小数点
test float 11 2

INSERT INTO dept ( test ) VALUES ( 140000.1 );
结果 140000.09
测试 130000.1 是好用的 感觉是float存储或是损失精度造成的,但不知道具体原因

你的代码应该是写给下一个开发者的情书。
附言 1  ·  2年前

找到临界点了 131071.10 可以 131072.10 就变成131072.09了

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 7
chowjiawei

改成string 模型set弄好小数点即可

2年前 评论
lalall (楼主) 2年前
aab 2年前
lalall (楼主) 2年前

IEEE 浮点数编码是一个很大的议题,IEEE 规定使用 (-1)^s×M×2^E 这个公式来表示浮点数。这里假设是单精度,即用 32 个 bit 来编码。其中:

  • s 用于表示正负数,用一个 bit 来编码 s,故而 s 的取值有 0 和 1。当 s 为 0 时,表示正数;反之表示负数。
  • M 用来表示小数部分,用 8 个 bit 来编码 M。
  • E 则是用来对小数部分加权用的,用剩下的 23 个 bit 编码 E。

所以,不可能用有限的位数来编码无限多的数字。如果一个有理数能够写成 a×2^b 这样的形式,例如 0.875 可以写成 1.75×2^(-1),就能够被”准确的”编码(只要不超过表示范围)。其他的当然也能够被编码,但是超过 32 bit 的就要被截断。在支持 IEEE 浮点数的电脑上,截断采用的是向偶数进位的方式。

所以,如果你要存入的数,刚好能够被表示为 a×2^b 这样的形式,则这个数就会被正确的存入。反之就要被按照向偶数进位的方式进行近似,有的近似出来的刚好就是想要存入的,有的近似出来的和想要存入的就有误差。

不单单是 131072.10 会被”近似”错,131072.26 也会被”近似”错。这样的数有无穷多个。

2年前 评论
lalall (楼主) 2年前
随波逐流 2年前
ㅤㅤ (作者) 2年前

同,遇到这个坑。就像楼上的老哥说的,不能用有限位数存大于这个位数的小数,例如mysql我定义了一个字段amount,l类型为decimal,长度为(20,3),现在有一个数12.1234,那么最终存入数据库的只有12.123。 但是如果涉及到钱(定长),就必须要用decimal,因为钱(RMB)在接入支付后最小的单位是1分,换算成“元”,就是小数0.01,那么decimal就应该定义为(n,2)或者(n,3)。涉及到钱的,建议使用如果使用decimal存储。其他根据实际情况使用,或者对小数进行处理后保存。 但是,就算是使用String类型,也有可能出现在前端渲染的时候出问题,例如总数是13.1,就有可能显示为:12.09999998。

2年前 评论

一般都用double;涉及金钱都用decimal

2年前 评论

金钱的直接用int 单位默认分

2年前 评论

不要用float用decimal

2年前 评论

不要用 float 用 decimal

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!