activerecord—为什么mysql会将float 6.099990904632568截断为6.1

rryofs0p  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(408)

我知道float是一个近似值,它取决于你想要的精度。然而,我不明白为什么它会转变 6.099999904632568 进入 6.1 . 为什么它需要圆化它而不是停止在它的最大精度(即。 6.09999990 )
不管怎样,我是否可以强制一个数字以其最大精度存储而不进行四舍五入?

表信息 CREATE TABLEurls(idint(11) NOT NULL AUTO_INCREMENT,gcloud_magnitudefloat DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB AUTO_INCREMENT=1193 DEFAULT CHARSET=utf8; ##要复制的代码

mysql> INSERT INTO urls (url_md5, gcloud_magnitude, created_at, updated_at) VALUES ('noop', 6.099999904632568, '2018-09-16 14:57:49', '2018-09-16 14:57:49'); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM urls WHERE url_md5 = 'noop'\G; id: 1193 url_md5: noop gcloud_magnitude: 6.1 1 row in set (0.00 sec) ##ruby解释器解析为float irb(main):004:0> Url.find_by(url_md5: 'noop').gcloud_magnitude.to_f => 6.1

disbfnqx

disbfnqx1#

我想总结一下我的发现作为答案。
当我保存值时,例如 6.099999904632568 mysql将其表示为float数据类型 6.1 . 当我将数据类型更改为 decimal with precision 64 and scale 30 ,的 6.099999904632568 自动出现,无需我更新值。
看起来mysql确实保存了数字的原始表示形式,但是没有办法以浮点形式返回该值。当我将数据类型转换为decimal时,mysql知道如何正确地表示它并正确地返回它。
这让我很困惑。如果mysql知道原始的表示形式,为什么我不能在没有将其类型转换为float的情况下取回原始值呢。还有,自从 6.099999904632568 比4字节所能处理的精度更高,它如何存储原始表示?
更多与原始问题无关的问题。

arknldoa

arknldoa2#

这个 FLOAT mysql中的数据类型没有足够的精度来存储您提供的值。这个 DOUBLE 数据类型可以做到这一点。
例子:

mysql> create table f ( f float, d double);

mysql> insert into f values (6.099999904632568, 6.099999904632568);

mysql> select * from f;
+------+-------------------+
| f    | d                 |
+------+-------------------+
|  6.1 | 6.099999904632568 |
+------+-------------------+
``` `FLOAT` 将值舍入到它可以存储的精度。事实上,舍入发生在精度低于所用值的值上。

mysql> select * from f;
+---------+-------------------+
| f | d |
+---------+-------------------+
| 6.1 | 6.099999904632568 |
| 6.1 | 6.0999999 |
| 6.1 | 6.099999 |
| 6.09999 | 6.09999 |
+---------+-------------------+

32位的内存中没有足够的位 `FLOAT` 存储无限精度。所以它必须舍入这个值。
你会发现一个物体的精确度是有限度的 `DOUBLE` 也。它以64位格式存储值。
uurv41yg

uurv41yg3#

你看到的价值, 6.1 ,可能是所谓的往返输出。这是最短的输出,在解析时,将返回与原来相同的值。并不是所有语言的输出都是浮动的或双倍的,但是有些语言是浮动的,除非明确地告诉别人。我想鲁比就是其中之一。
价值 6.1 ,当解析为float时,获取确切的值 6.099999904632568359375 ,但价值 6.099999904632568 ,解析时,获取完全相同的值。 6.1 是可以为该特定浮点生成的最短输出,当读回(再次解析)时,它将生成相同的浮点。

相关问题