Mysql 浮点数是多少?

Mysql 浮点数是多少?,mysql,floating-point,limit,digits,maxlength,Mysql,Floating Point,Limit,Digits,Maxlength,我找遍了,找不到这个答案 MySQLFLOAT的实际位数是多少 我知道(思考?)它截断了超出浮点值的4字节限制的内容,但这到底是什么?来自(我的重点): 对于FLOAT,SQL标准允许一个可选的 精度(但不是指数的范围),单位为 括号中的关键字FLOAT。MySQL还支持这个可选的 精度规格,但精度值仅用于 确定存储大小。从0到23的精度将导致4字节 单精度浮点列。精度从24到53的结果是 8字节双精度双列 因此,尾数的精度位最多可以存储在浮点中,这相当于大约7位十进制数字,因为2^23~10^

我找遍了,找不到这个答案

MySQL
FLOAT
的实际位数是多少

我知道(思考?)它截断了超出
浮点值
的4字节限制的内容,但这到底是什么?

来自(我的重点):

对于FLOAT,SQL标准允许一个可选的 精度(但不是指数的范围),单位为 括号中的关键字FLOAT。MySQL还支持这个可选的 精度规格,但精度值仅用于 确定存储大小。从0到23的精度将导致4字节 单精度浮点列。精度从24到53的结果是 8字节双精度双列


因此,尾数的精度位最多可以存储在浮点中,这相当于大约7位十进制数字,因为2^23~10^7(8388608 vs 10000000)。我测试过了。您可以看到返回的是12位小数,其中只有前7位是真正准确的。

对于那些认为MySQL对待浮点与JAVA一样的人,我得到了一些令人震惊的消息:MySQL将可用的精度降低为浮点,以便向您隐藏可能不正确的小数点!看看这个:

爪哇:

输出是

long i = 16777225 becomes 16,777,224
到目前为止,一切正常。我们的示例整数略高于2^24=16777216。由于23位尾数,介于2^23和2^24之间,浮点可以容纳每个整数。然后从2^24到2^25,它只能保存偶数,从2^25到2^26,它只能保存可被4整除的数,依此类推(同样在另一个方向:从2^22到2^23,它可以保存0.5的所有倍数)。只要指数没有超出范围,这就是浮点可以存储的规则

16777225是奇数,因此“浮点版本”是一次性的,因为在该范围内(从2^24到2^25),浮点的“步长”是2

现在,MySQL如何理解它呢

这是小提琴,以防你不相信我(我不会)

结果:

16777200

结果是25,而不是1,但有“优势”是可以被100整除。非常感谢

我想我理解这一派胡言背后的“哲学”,但我不能说我赞成。以下是“原因”:

他们不想让您看到可能错误的小数位,他们通过将“实际”浮点值(JAVA中的浮点值和行业标准中的浮点值)四舍五入到适当的十次方来实现这一点

在这个例子中,如果我们保持原样,最后一个数字是错误的,不是零,我们不能得到它

然后,如果我们四舍五入到10的倍数,正确的值将是16777230,“实际”浮点值将四舍五入到16777220。现在,第7位是错的(以前没有错,但现在是),而且不是零。我们不能那样。最好四舍五入到100的倍数。现在,正确的值和“实际”浮点值都四舍五入到16777200。所以你只能看到6个正确的数字。您不想知道结尾的“24”,告诉您(因为该范围内的步长为2)原始数字必须在1677723和1677725之间。不,你不想知道;这两个数字在四舍五入到第七位后在第七位不同,因此您无法知道“正确的”第七位,因此您希望在第六位停止。不管怎样,这就是他们认为你在MySQL想要的

因此,他们的目标是四舍五入到一些十进制数字(即6),这样这6位数字总是“正确的”,因为如果你将原始的精确数字(在转换为浮点之前)四舍五入到6位,你会得到相同的6位数字。由于log_base10(2^23)=6.92,四舍五入为6,我可以理解为什么他们认为这总是有效的。可悲的是,事实并非如此

例如:

i=33554450

这个数字介于2^25和2^26之间,所以它的“float版本”(即JAVA float版本,而不是MySQL float版本)是4的最接近倍数(较小的一个,如果它在中间),因此

i_as_float=33554448

我四舍五入到6位小数(即100的倍数,因为它是8位数字)得到33554500

i_as_float四舍五入到6位小数得到33554400

哎呀!这些数字在第6位不同!但是不要告诉MySQL的人。他们可能只是开始将16777200“提高”到16777000

更新

其他数据库不是这样做的


小提琴:

从文档中,一些背景阅读:@martinclayton-heh,谢谢你,但已经全部结束了。只是想知道我应该如何限制phpso中的
bc()
,当我问一个问题时,我经常感到尴尬。真不敢相信我错过了。泰!嗯,我错了。它是23位,实际上相当于大约7位。令人烦恼的是,关于这一点的最佳文档似乎是SQL Server的文档:。当我使用SQLFIDLE测试时,它将返回大约12位小数,其中前7位是准确的:奇怪的是,即使是一个简单的
INSERT
也会出现故障。非常感谢您提供详尽的证据!16777225实际上由MySQL存储为16777224,但在检索时四舍五入为16777200。您可以通过手动舍入来解决此问题:
从test
中选择舍入(test,0)。或者,例如,将
test
列定义为
FLOAT(10,0)
。浮动的默认(显示)精度确实令人非常困惑!在任何情况下,使用整数类型存储整数。十进制通常是比浮点更好的选择。
long i = 16777225 becomes 16,777,224
CREATE TABLE IF NOT EXISTS `test` (
     `test` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `test`(`test`) VALUES (16777225)

SELECT * FROM `test`