为什么MATLAB中计算3^34时,结果为16677181699666568,而实际上3^34=16677181699666569?用MATLAB计算3^34、5^23、7^19时,结果分别为16677181699666568、11920928955078124、11398895185373144。而实际上3^34=16677181699666568+1、5^2
来源:学生作业帮助网 编辑:六六作业网 时间:2024/12/29 20:26:00
为什么MATLAB中计算3^34时,结果为16677181699666568,而实际上3^34=16677181699666569?用MATLAB计算3^34、5^23、7^19时,结果分别为16677181699666568、11920928955078124、11398895185373144。而实际上3^34=16677181699666568+1、5^2
为什么MATLAB中计算3^34时,结果为16677181699666568,而实际上3^34=16677181699666569?
用MATLAB计算3^34、5^23、7^19时,结果分别为16677181699666568、11920928955078124、11398895185373144。而实际上3^34=16677181699666568+1、5^23=11920928955078124+1、7^19=11398895185373144-1。但计算3^33、5^22、7^18时,结果都是正确的。
回复:
liuxinzhang123,没看懂,能不能麻烦你讲详细些?
hokvens、dwangli,不对,当然没超过运算最大位数的上限咯,比如2^100=1267650600228229401496703205376是正确的,显然2^100比3^34位数多。
csg974,请问double类型为什么不准,能不能讲具体些?
为什么MATLAB中计算3^34时,结果为16677181699666568,而实际上3^34=16677181699666569?用MATLAB计算3^34、5^23、7^19时,结果分别为16677181699666568、11920928955078124、11398895185373144。而实际上3^34=16677181699666568+1、5^2
太大或者太小的数想准确计算的话,用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位小数,只是影响显示,不影响实际的值.
matlab的有效位数应该只有15位吧。。。不太清楚,你这个应该是整数的计算
超过运算最大位数的上限了,不信你再试试更大的数,显示给你的结果更不准 。
但要记得,在MATLAB内部,它的数值是准确的,你定义
temp = 3^34;
虽然显示的值不准 ,但运算的时候你可以试试temp/3^30,肯定还是81.
那个模式是偶数模式