使用JPA
映射一个float
类型到数据库:html
而后存储129364.57
,发现存储的结果是129365
。mysql
从上周就开始研究这个问题,查阅了各类资料,网上许多人都说是由于MySQL
默认是保留六位有效数字,本身测试了一下也确实是这样。可是查询MYSQL
官方文档,并无找到依据。sql
MySQL
官方文档:Float - MySQL数据库
若是你看到了这篇文章,欢迎评论发表意见,让咱们互相学习、进步。segmentfault
写的很是好的一篇文章,MySQL
存储的各类尝试:MySQL数字类型int与tinyint、float与decimal如何选择性能
用JPA
映射的Float
默认的长度与小数点都是0
。学习
这是测试的结果:
float
默认能精确到6位有效数字!
这是MySQL
官方文档对float
和double
的描述:测试
官方文档并无说
MySQL
是如何存储浮点数的,因此若是没有去读过其源代码,全部的博客都只是猜测。
目前大多数人认为MySQL
内部是采用IEEE 754
进行存储的,IEEE 754 - 维基百科。优化
IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最普遍使用的浮点数运算标准,为许多CPU与浮点运算器所采用。
以32
位的单精度浮点数为例:spa
与平常所说的科学计数法相似。
由于底数是有效数字,因此第一位确定是1
,因此这个1
不进行存储,因此虽然是23
位的底数,可是实际的底数位数实际上是24
位,含有一个隐含的1
。
双精度与此相似,一个符号位,指数位为11
,尾数为52
位,合计64
位。
假设是用MySQL
是用IEEE 754
标准存储的浮点数。
用单精度存储129364.57
,其二进制为11111100101010100.1001000111101011100001010001111011
。
正数:符号位为0
。
指数位为:00010000
(十进制中的16
)。
去掉第一个1
,保留23
位,底数为:11111001010101001001000
。
因此最后的结果是11111100101010100.1001000
,转换为十进制为:129364.5625
。
可是实际的MySQL
存储后的结果为129365
,因此猜测要么MySQL
就是否是按IEEE 754
存储的,要么就是按这个存储的可是内部为了数据库的性能等或其余的优化对数据进行了处理。
这里我这里更倾向于第二种,毕竟IEEE 754
是一种国际标准,没有理由不遵照。