MySQL (MariaDB) 浮动可视化:为什么值四舍五入到百或千?
MySQL (MariaDB) float visualization: why are values rounded to hundreds or thousands?
首先:我是一个 MySql 新手,看来我在这里遗漏了一些重要的东西。
在 MySQL 数据库中,我的浮点值范围从单位到十亿。
我花了几天时间试图理解为什么所有这些都显示不超过 6 位有效数字,而不太重要的数字设置为 0:
即:
select `field` from `table`;
(instead of X -> i get Y)
1 -> 1
12 -> 12
123 -> 123
1234 -> 1234
12345 -> 12345
123456 -> 123456
1234567 -> 1234570
12345678 -> 12345700
123456789 -> 123457000
只有 "trick" 我才找到可以读取真实值的地方:
select `field`+0.0 from `table`;
我的问题:这种(恕我直言)奇怪行为背后的基本原理是什么?文档中在哪里描述了它?
我发现完全不直观的是,我没有看到正常的 select * 的实际值(当然是根据 IEEE 规范近似),但我需要这个技巧......我在这里错过了什么?
一个FLOAT
有24位,或者log<sub>10</sub>(2<sup>24</sup>)
(超过7)位,意义:12345678.9<sub>10</sub>
存储在FLOAT
中为101111000110000101001111<sub>2</sub>
(即 12345679<sub>10</sub>
)。当显示为十进制时,客户端肯定从第8位开始的所有内容都是肯定false precision(因为FLOAT
只能存储 7 个十进制数字的精度)。因此,它会丢弃其余部分,只剩下 12345680
.
一个DOUBLE
有53位,或者log<sub>10</sub>(2<sup>53</sup>)
(差不多16)个数字,意义重大:12345678.9<sub>10</sub>
存储在一个DOUBLE
中为101111000110000101001110.11100110011001100110011001101<sub>2</sub>
(即 12345678.90000000037<sub>10</sub>
)。当显示为十进制时,客户端肯定从第16位开始的所有内容肯定false precision(因为DOUBLE
只能存储 15 位十进制数字的精度)。因此,它会丢弃其余部分,只剩下 12345678.9000000
.
添加 +0.0
时,MySQL 首先将 FLOAT
转换为 DOUBLE
。
我忽略了float和double按照IEEE754的表示法,这就是这个谜的解法
FLOAT(32 位)的尾数为 23 位(8 百万个可能值 => 6 个有意义的数字),其他 9 位用于符号和指数。
DOUBLE(64 位)有 52 位的尾数(一些 4.5e15 可能的值 => 14 个有意义的数字)。
这意味着 Mysql 无法显示不存在的内容(在我的例子中是 FLOAT 大数字)并用零填充 "random" 无意义的数字。
首先:我是一个 MySql 新手,看来我在这里遗漏了一些重要的东西。
在 MySQL 数据库中,我的浮点值范围从单位到十亿。 我花了几天时间试图理解为什么所有这些都显示不超过 6 位有效数字,而不太重要的数字设置为 0:
即:
select `field` from `table`;
(instead of X -> i get Y)
1 -> 1
12 -> 12
123 -> 123
1234 -> 1234
12345 -> 12345
123456 -> 123456
1234567 -> 1234570
12345678 -> 12345700
123456789 -> 123457000
只有 "trick" 我才找到可以读取真实值的地方:
select `field`+0.0 from `table`;
我的问题:这种(恕我直言)奇怪行为背后的基本原理是什么?文档中在哪里描述了它? 我发现完全不直观的是,我没有看到正常的 select * 的实际值(当然是根据 IEEE 规范近似),但我需要这个技巧......我在这里错过了什么?
一个
FLOAT
有24位,或者log<sub>10</sub>(2<sup>24</sup>)
(超过7)位,意义:12345678.9<sub>10</sub>
存储在FLOAT
中为101111000110000101001111<sub>2</sub>
(即12345679<sub>10</sub>
)。当显示为十进制时,客户端肯定从第8位开始的所有内容都是肯定false precision(因为FLOAT
只能存储 7 个十进制数字的精度)。因此,它会丢弃其余部分,只剩下12345680
.一个
DOUBLE
有53位,或者log<sub>10</sub>(2<sup>53</sup>)
(差不多16)个数字,意义重大:12345678.9<sub>10</sub>
存储在一个DOUBLE
中为101111000110000101001110.11100110011001100110011001101<sub>2</sub>
(即12345678.90000000037<sub>10</sub>
)。当显示为十进制时,客户端肯定从第16位开始的所有内容肯定false precision(因为DOUBLE
只能存储 15 位十进制数字的精度)。因此,它会丢弃其余部分,只剩下12345678.9000000
.
添加 +0.0
时,MySQL 首先将 FLOAT
转换为 DOUBLE
。
我忽略了float和double按照IEEE754的表示法,这就是这个谜的解法
FLOAT(32 位)的尾数为 23 位(8 百万个可能值 => 6 个有意义的数字),其他 9 位用于符号和指数。 DOUBLE(64 位)有 52 位的尾数(一些 4.5e15 可能的值 => 14 个有意义的数字)。
这意味着 Mysql 无法显示不存在的内容(在我的例子中是 FLOAT 大数字)并用零填充 "random" 无意义的数字。