为什么DECIMAL(38,0)的取值范围是-1038+1到1038-1?

数据库中,Decimal数据类型,语法为:Decimal(P,S),P为精度,s为数字的小数位数,精度P的取值范围是:1到38,

S的取值范围是0到P从而得出Decimal数据类型的取值范围是-1038+1到1038-1,请问这个取值范围是怎么得出的呀?谢谢啦!

问题出处:http://zhidao.baidu.com/question/202258324.html



尝试回答如下几个问题

1.什么是decimal?

2.什么是精确度?

3.什么是科学计数法?

4.如果使用float会和decimal有什么不同?

5.为什么技术内幕里面的科学计数法使用2作为底数?

6.为什么说decimal的精度比较高?

7.mysql如何计算10的10次方?

8.科学计数法的E是怎么回事?

 


生活中有些数字无限长,比如圆周率3.1415926535897932384626433832795028841971693....... 这么长

mysql数据库的任何一个数据类型,都无法装下这个无限大的值

这时候有两种方法处理

1. 从某一位开始截取,用四舍五入的方式,这叫做取它的近似值,比如使用float和double的数据类型

2.从某一位开始截取,但不用四舍五入的方式,这叫做准确值,比如使用decimal的数据类型,别名是numeric和fixed

也正因为decimal不会出现四舍五入,所以很适合保存货比值,比如移动的话费就用decimal来装的

 

截取得位数越多,这个值越贴近准确值,截取得位数越少,越偏离准确值

比如3.14159这个值,肯定比3.14这个值,更接近 π ,也就是前者的精确度越高

定义:精度 = 有效位数,precision ,但是mysql的书籍,通常用m来表示 #内幕 140

如3.14159的精度为6, 3.14的精度为3

小数点后的位数,称之为小数精度,scale,缩写为s

当然P和S的值不可以无限大的,它是有一个范围的

在mysql数据库里,p的范围[1,65],s的范围[0,33],其中s<p 

 

数字有一个属性,正和负

所以加上这个属性之后,当一个列定义为DECIMAL(4,1)类型,它的取值范围是[-999.9,999.9]

精度P的取值范围是:1到38,S的取值范围是0到P从而得出Decimal数据类型的取值范围是-1038+1到1038-1

S取值范围是0,意思是小数部分为0,这个DECIMAL为正数

因为正负属性,当P取- 38时,数据可以得到最小值 ,当 P 取38时,数据可以得到最大值

|---38位---| |----38位----|
取值范围 [ - 999......999 , + 999 ......999 ]


什么是科学计数法?

生活中有些数字非常的大,读起来,写起来都很不方便

比如光的速度 300000km/s,比如上面连续38位9
为了方便记录,有了科学计数法——把任意数字表示成为  a * 10^n 其中a取值范围 [0,1 ]
 

                 |----38位---|     |-----38位----|

取值范围 [ - 999......999 , + 999 ......999 ]

为了让它好看点,给它加上1

                  |---38位----|     |----38位----|

             [- 1000......000 , 1000......000]

使用科学计数法表表示[-1*10^38 ,1*10^38]

这时候再把原来的加1给减去,就得到结果,decimal(38,0)的取值范围 [ - 1*10^38- 1 ,1*10^38- 1]


 

4.为什么说decimal的精确度比float和double要高呢?

使用decimal(5,4)和使用float(5,4)去装数据3.1415926有什么不同呢?

create table t 
(
     decimal_col  decimal(5,4),
     float_col       float(5,4)
);

insert into t (decimal_col , float_col) values (3.1415926,3.1415926);


  

我的mysql版本是5.6,这里decimal拥有了四舍五入功能,而不像《技术内幕》说的不会四舍五入

create table t(
     decimal_col decimal(65,0),         #decimal的精度最高是65位
     float_col  float(65,0),            #float的精度最高是255位,但只取65位比较       
double_col double(65,0) );

接下来去验证 decimal,float,double谁的值更准确(精度更好)

 

当我们插入1E2-2时(即10的2次方-2)

truncate table t;
insert into t values (1E2-2,1e2-2,1e2-2);

  

这时decimal,float,double都可以得出正确的结果

 

当我们插入1E10-2时(即10的10次方-2)

truncate table t;
insert into t values (1E10-2,1e10-2,1e10-2);

  

这时decimal和double可以得出准确结果,但float已经不能得出了

 

当我们插入1E17-2时(即10的17次-2)

truncate table t;
insert into t values (1E17-2,1e17-2,1e17-2);

  

这时float早已经语无伦次,而decimal和double都已经忽略了-2了,同样不能得出正确结果了

 

结论:数值越大,运算的精确度越低

 

posted @ 2015-10-20 16:52  lawrence.li  阅读(8281)  评论(1编辑  收藏  举报