MySQL下的浮点类型使用了一些错误细节
使用IEEE754标准的浮点数在计算机内部,用二进制表示
例如:7.22与32位二进制没有指示。
所以不准确。
MySQL中浮点数据类型的总结
对于单精度浮点浮点数:当数据在±131072(65536×2)的范围内时,浮点数据的精度是正确的,但超出了数据范围的不稳定,没有找到相关参数,将浮点改为double或十进制,两者之间的差值是双浮点运算。小数是定点计算,得到更精确的数据。
1.float型
浮动列类型的默认长度不检查结果,必须指定精度。
例如,Num浮动,插入到表(努姆)值(0.12)中;从表0.12中选择*。
复制代码代码如下所示:
Num浮(9,7),插入表格(努姆)值(0.12);选择*从桌子上会发现这个记录。
创建表
(->
数浮(9)
>;
查询OK,0行受影响(0.03秒)
插入到TT(努姆)值中(1234567.8);
错误1264(22003):超出范围值column'num'at排1
注意:超出了字段范围,不能插入
代码遵循复制代码如下所示
插入到TT(努姆)值中(123456.8);
查询OK,1行受影响(0秒)
从TT选择*;
------------ + +
| Num |
------------ + +
123456.797 | |
------------ + +
1行集(0秒)
注:十进制数是不够的,但有一个问题,就像上面的近似值。
复制代码代码如下:mysql插入到TT(努姆)值中(123456.867);
查询OK,1行受影响(0.04秒)
从TT选择*;
------------ + +
| Num |
------------ + +
123456.797 | |
123456.797 | |
123456.867 | |
------------ + +
3行(0秒)
编号为123456.867的TT;
------------ + +
| Num |
------------ + +
123456.867 | |
------------ + +
1行集(0秒)
插入到TT(努姆)值中(2.8);
查询OK,1行受影响(0.04秒)
从TT选择*;
------------ + +
| Num |
------------ + +
123456.797 | |
123456.797 | |
123456.867 | |
2.800 | |
------------ + +
4行(0秒)
编号为2.8的TT;
------- + +
| Num |
------- + +
2.800 | |
------- + +
1行集(0秒)
插入到TT(努姆)值(2 888888);
查询OK,1行受影响(0秒)
从TT选择*;
------------ + +
| Num |
------------ + +
123456.797 | |
123456.797 | |
123456.867 | |
2.800 | |
2.889 | |
------------ + +
5行(0秒)
注意:数字的数目已超过,并且近似值是自动取下的。
首先,浮点数的概念和误差问题。
浮点数是表示实数的一种方法。它代表了实数与M(尾数)×B(基数)E(指数)功率的平方。与固定数相比,它在一定长度下具有数据范围大的特点,但同时也存在误差问题。这是著名的浮点数精度问题。浮点数的方式多种多样,在浮点计算机实现符合IEEE754标准,IEEE754提供单精度浮点数和双精度浮点数两种规格,单精度浮点数由4个字节(32bit)说浮点格式是1位符号位8位23位的尾数双精度浮点数的8字节(64bit)说真正的格式为:1位符号位11位52位尾数的指数在同一时间,该尾数IEEE754格式规范:D. dddddd,左…小数点只有1和不为零,计算机里面是二进制的,所以尾数小数点左边的部分都是1。显然,这1个可以略提高尾部的精度。众所周知,单精度浮点数尾数表示24bit,和双精度浮点数的尾号是表示53bit并转换成十进制:
2 = 24 - 1 = 16777215;2 = 53 - 1 = 9007199254740991
它从上面可以看出,有效位数的二进制IEEE754单精度浮点数为24位,按十进制系统,它是8位的。有效位数的二进制数的双精度浮点数是53位,这16位按十进制系统。显然,如果一个实数的有效人数超过8位,单精度浮点数是用来做了一个错误。同理,如果实数一个有效的数量超过16位,双精度浮点数是用来做错误。对于1310720000000000000000.66数,有效数字24位。误差由单精度或双精度浮点数生成,但程度不同。
单精度浮点数:1310720040000000000000.00;双精度浮点数:1310720000000000000000.00
可以看出,双精度为0.66,单精度接近4兆!
上面显示的是长度限制引起的错误,但这并不是全部!IEEE754标准的浮点数是二进制的内部表示,但是它也可以导致错误转换成一个十进制数的二进制浮点数时。其原因是所有的数字都可以转换成有限长度的二进制数,131072.32的有效数字是8位,原因应该是能够精确地表示单精度浮点数。为什么会有偏差在数据的二进制数看,我们可以看到,10000000000000000001010001…显然,其尾数超过24bit。根据尾数舍入规则,只需要100000000000000000010100,导致奇怪的现象在test.131072.68遇到的单精度浮点数为131072.69,其原因是类似的。事实上,有效数8以内数、浮点数可能无法准确地代表数字7.22,尾数不能使用24bit二进制表示,当然是在数据库测试没有问题(圆或7.22之后),但如果在一些计算,累积误差,会产生较大的偏差。
二、MySQL和oracle中的数值类型
问题是,这仅仅是MySQL的存在吗显然不是,还有只要符合IEEE754标准的浮点数实现同样的问题。
MySQL中的数字类型(不包括整数):
IEEE754浮点数:float(单精度),双房(双精度)
定点数:小数或数值
oracle中的数字类型:
Oracle浮点数:编号(通知不指定精度)
IEEE754浮点数:binary_float(单精度),binary_double(双精度)浮子,浮子(N)(数据类型所要求的标准)
定点数:数字(P,s)
如果你测试Oracle与binary_float等等,结果都是一样的。因此,在数据库中,以货币或其他精密敏感的数据,我们应该使用固定数量的存储,MySQL是十进制,Oracle数(P,S),双精度的浮点数也有问题,对于较大的数据。
三,浮点数在程序设计中也存在一个问题。
不仅在数据库中有浮点运算的问题,编程也是一样的,甚至可以说更值得注意!
通过以上的介绍,对浮点数的误差问题,应该更清楚。如果一个复杂的浮点数是一个程序执行,错误将被进一步放大。因此,在程序设计中,如果使用的是浮点数,要实现可能的误差问题。不仅那,如果浮点数处理不好,它也会导致程序错误!看下面的语句:如果(x)!y = 1 (x y);}这个语句似乎不是问题,但是如果它是浮点数,可能会有问题!看看下面的语句会输出什么结果:公共{公共类测试static void main抛出异常(字符串{ } args){ system.out.print(7.22-7.0 =+(7.22f-7.0f));} }我们可以想当然的输出可以是0.22,实际结果是0.21999979!
因此,在程序设计中,我们应该尽量避免浮点数比较,否则可能会导致一些潜在的问题。除了这些,我们还应该注意到浮点数的一些特殊值,如南,+ 0,0 +无穷大,无穷大,等虽然IEEE754有关于这个协议,会有具体的实现方法和不同的硬件结构之间的差异。如果我们不注意,我们也会犯错误。
四。总结:
根据以上分析,我们可以得出以下结论:
1,浮点数中存在一个错误问题。
2。精度敏感数据,如货币,应该用固定点数表示或存储。
3,在编程中,如果使用浮点数,应特别注意误差问题,尽量避免浮点数的比较。
4。应注意对浮点数中一些特殊值的处理。
注意事项
在MySQL 5.022中,
如果字段F是浮点类型,那么在查询中,SQL语句是:
从T选择f=2.2;
因此,即使是表中2.2的数据也不能查询。
这个解决方案有2种解决方案。
1、将浮点改为double类型。这不会发生。但是,如果数据库中的数据量很大或修改量太大,则不适合此方法。该方法只适用于数据库的早期设计。
2。设置浮点的精度,然后查询它。
如果你要精确到3位,选择*从这里格式(F,3)=(2.2,3)格式;
但准确率不能超过6。或错误,因为浮点类型被允许精确到小数点后的6位。