数据库双精度mysql_mysql中float、double、decimal三种类各朝代统治时间
型,以及。。。
单精度浮点数⽤4字节(32bit)表⽰浮点数,采⽤IEEE754标准的计算机浮点数,在内部是⽤⼆进制表⽰的,如:7.22⽤32位⼆进制是表⽰不下的,所以就导致不精确了,存取会出现误差。
mysql中float数据类型的问题总结:
对于单精度浮点数float:当数据范围在±131072(65536×2)以内的时候,float数据精度是正确的,但是超出这个范围的数据就不稳定。
王维舟建议:将float改成double或者decimal,两者的差别是double是双精度浮点计算,decimal是定点计算,会得到更精确的数据。
float列类型默认长度查不到结果,必须指定精度。
插⼊数据长度不够会⾃动补齐⼩数位,补齐的⼩数取近似值。
例如:num(9,3)就是总长度9位,包含3位⼩数,如果插⼊的数据是 12345678.9,长度是9位,再加上补齐的两位⼩数则成为12345678.897,超出字段范围,⽆法插⼊。
如果插⼊的是123456.9,则会补齐⼩数,取近似值 123456.797,正好可以插⼊,但再取出来的时候就不是你插⼊的那个了,就变成了123456.797(近似值)。
⼩数位数超了,⾃动取近似值。
例如:插⼊2.888888,插⼊到数据库中的结果是 2.889
课间活动作文⼀、浮点数的概念及误差问题
浮点数是⽤来表⽰实数的⼀种⽅法,它⽤ M(尾数) * B( 基数)的E(指数)次⽅来表⽰实数,相对于定点数来说,在长度⼀定的情况下,具有表⽰数据范围⼤的特点。但同时也存在误差问题,这就是著名的浮点数精度问题!浮点数有多种实现⽅法,计算机中浮点数的实现⼤都遵从IEEE754 标准,IEEE754 规定了单精度浮点数和双精度浮点数两种规格,单精度浮点数⽤4字节(32bit)表⽰浮点数,格式是:1位符号位8位表⽰指数 23位表⽰尾数 双精度浮点数8字节(64bit)表⽰实数,格式是:1位符号位 11位表⽰指数 52位表⽰尾数 同时,IEEE754标准还对尾数的格式做了规范:,⼩数点左⾯只有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位,按理应该能⽤单精度浮点数准确表⽰,为什么会出现偏差呢?看⼀下这个数据⼆进制尾数就明⽩了 显然,其尾数超过了24bit,根据舍⼊规则,尾数只取
北条氏直
100000000000000000010100,结果就造成测试中遇到的“奇怪”现象!131072.68 ⽤单精度浮点数表⽰变成 131072.69 ,原因与此类似。实际上有效数字⼩于8位的数,浮点数也不⼀定能精确表⽰,7.22这个数的尾数就⽆法⽤24bit⼆进制表⽰,当然在数据库中测试不会有问题(舍⼊以后还是7.22),
但如果参与⼀些计算,误差积累后,就可能产⽣较⼤的偏差。
⼆、mysql 和 oracle中的数值类型
问题是不是只有 mysql 存在呢?显然不是,只要是符合IEEE754标准的浮点数实现,都存在相同的问题。
mysql中的数值类型(不包括整型):
IEEE754浮点数:float(单精度),double或real(双精度)
定点数:decimal或numeric
oracle中的数值类型:
oracle 浮点数 :number(注意不指定精度)
IEEE754浮点数:BINARY_FLOAT(单精度),BINARY_DOUBLE(双精度)FLOAT,FLOAT(n) (ansi要求的数据类型)
定点数:number(p,s)
如果在oracle中,⽤BINARY_FLOAT等来做测试,结果是⼀样的。因此,在数据库中,对于涉及货币或其他精度敏感的数据,应使⽤定点数来存储,对mysql来说是 decimal,对oracle来说就是number(p,s)。双精度浮点数,对于⽐较⼤的数据同样存在问题!
三、编程中也存在浮点数问题
不光数据库中存在浮点数问题,编程中也同样存在,甚⾄可以说更值得引起注意!
行测答题时间通过上⾯的介绍,浮点数的误差问题应该⽐较清楚了。如果在程序中做复杂的浮点数运算,误差还会进⼀步放⼤。因此,在程序设计中,如果⽤到浮点数,⼀定要意识到可能产⽣的误差问题。不仅如此,浮点数如果处理不好,还会导致程序BUG!看下⾯的语句:if (x != y) { z = 1 / (x -y);}这个语句看起来没有问题,但如果是浮点数,就可能存在问题!再看下⾯的语句会输出什么结果: public class Test { public static void main(String[]args) throws Exception { System.out.print("7.22-7.0=" + (7.22f-7.0f)); } } 我们可能会想当然地认为输出结果应该是 0.22 ,实际结果却是 0.21999979 !
因此,在编程中应尽量避免做浮点数的⽐较,否则可能会导致⼀些潜在的问题!除了这些,还应注意浮点数中的⼀些特殊值,如 NaN、
+0、-0、+⽆穷、-⽆穷等,IEEE754虽然对此做了⼀些约定,但各具体实现、不同的硬件结构,也会有⼀些差异,如果不注意也会造成错误!
四、总结:
从上⾯的分析,我们可以得出以下结论:购物英语怎么读
1、浮点数存在误差问题;
2、对货币等对精度敏感的数据,应该⽤定点数表⽰或存储;
3、编程中,如果⽤到浮点数,要特别注意误差问题,并尽量避免做浮点数⽐较;
4、要注意浮点数中⼀些特殊值的处理
注意事项
MYSQL 5.022中,
如果某个字段 f是float类型,那么在查询的时候,sql语句为:
lect * from T where f = 2.2;
那么即使表中有2.2的数据也不能被查询到.
此时解决⽅法有2种:
1.将float改为double类型,不会出现这种问题.但是如果数据库中数据量庞⼤,或者修改量太⼤,则不适合这个⽅法.这个⽅法只适合设计数据库的初期阶段.
2.设置float的精度然后进⾏查询就可以了.
如果要精确到3位,则:lect * from T where format(f,3) = format(2.2,3);
但是,精度不能超过6.否则出错.因为float类型最多允许精确到⼩数点后6位.粜怎么读音
来源: