太大或者太小的数想准确计算的话,用sym类型来计算。
>> sym(3)^34
ans =
16677181699666569
只不过需要注意的是结果也是sym类型,必要时需转换成double类型。
>> double(ans)
ans =
1.667718169966657e+016
至于为什么算出是16677181699666568,这跟计算机内部的浮点数表示法有关。
>> sym(3^34,'d')
ans =
16677181699666568.
这个是用十进制数表示,就是你知道的那个计算结果,不过这个结果是怎么来的呢?我换一种表示法,你看一下:
>> sym(3^34,'r')
ans =
8338590849833284*2^(1)
这种表示法是按有理数的表示法,也就是分数。
在sym的帮助里,'r'的说明里有这么一句话:
If no simple rational approximation can be
found, an expression of the form p*2^q with large integers p and q
reproduces the floating point value exactly. For example, sym(4/3,'r')
is '4/3', but sym(1+sqrt(5),'r') is 7286977268806824*2^(-51)
意思就是说如果不能用准确的有理数形式表达的话,那就用它的浮点数的值重新构成一个p*2^q这样形式的表达式。
看来,你要求的3^34已经超出准确表达的范围了,那么它的浮点数的值是什么样的呢?下面再换成浮点数的形式:
>> sym(3^34,'f')
ans =
'1.d9fe779881944'*2^(53)
这个就是浮点数在计算机中的实际存储形式了。一般我们说的double类型,就是64位的浮点数。有兴趣的话你可以查一查IEEE二进制浮点数的标准。
简单来说,64位的二进制浮点数,最高位为符号位,中间11位为指数(这里就是那个53),低52位为实际的有效数字(也就是d9fe779881944这部分,其中每个十六进制占4位,刚好13个,一共52位)。然后前面加上"1.",就是上面看到那个形式了。
看一下
>> hex2dec('1d9fe779881944') % hex2dec是十六进制转换成十进制
ans =
8338590849833284
因为有小数点,所以还要除以16^13=2^52,也就是乘以2^(-52)
那么'1.d9fe779881944'*2^(53)就变成
8338590849833284*2^(-52)*2^(53)
=8338590849833284*2^(1) 也就是前面那个有理数表示形式。
=16677181699666568 这个是十进制数的表示形式
好,现在再看为什么会出现结果末位是8而不是9,就比较容易理解了。
正是因为浮点数所能准确表示的有效数字,最多就是那52位二进制数,
所以超出范围的话,只能用52位的有效数字乘以2的幂来表示,那末位就一定是偶数,不可能出现奇数的,所以9是表示不出来的。
这还是只超过范围一位,要是超出更多,那表达式跟实际值可能相差的更多了。
因为你这个3^34是8338590849833284*2^(1),后面只是2^(1),所以误差不会超过2,最多就是1。
假如后面是2^(3),那跟实际值相差最多7,也就是2^n-1。
至于最前面,double形式等于1.667718169966657e+016 ,
这个就跟屏幕显示的位数有关了,我用的是format long g,
是显示15位小数,只是影响显示,不影响实际的值。
温馨提示:内容为网友见解,仅供参考