找回密码
 欢迎注册
查看: 39731|回复: 15

[讨论] Mathematica结果求测试求解释

[复制链接]
发表于 2014-10-26 17:15:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
  1. ToString[N[58/11], InputForm]
  2. ToString[N[74/15], InputForm]
  3. ToString[N[841/180], InputForm]
复制代码

未标题-1.png
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-10-26 17:28:43 | 显示全部楼层
问题何在?

没看到问题呢
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2014-10-26 18:45:58 | 显示全部楼层
wayne 发表于 2014-10-26 17:28
问题何在?

没看到问题呢

最后一位
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-10-26 19:09:02 来自手机 | 显示全部楼层
计算有误差,二进制内部首先有舍入,然后转化为十进制再次舍入

点评

这个应该没法深入分析的吧,感觉跟具体的实现有关  发表于 2014-10-26 21:12
假如我这么问:24/13 保留16位小数,舍入后最后一位是多少?我们具体该如何分析  发表于 2014-10-26 21:09
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-10-26 20:45:56 | 显示全部楼层
试一下这个命令
  1. FullForm[N[841/180]]
复制代码

你会发现有一个小角标,这个小角标在Mathematica里面叫做 NumberMarks ,用来标记 Precision  。
如果小角标后面没有跟数字,就表示默认的系统精度,MachinePrecision,即15.6位。

===
ToString函数的操作对象是 expr,即expr的FullForm形式,至于最后一位的舍入误差,为啥会是这么多,应该跟数的具体实现有关。

@mathe, mathe可否有兴趣挖掘出这个具体表达?
比如24/13,取小数点后16位(前15位是准确的,最后一位是带有误差),那么这个最后一位会是啥?

点评

是 1.8461538461538463  发表于 2014-10-28 15:09
对于24/13,我们可以先计算24*2^52/13.0~= 8314337773607069.538461538462,于是四舍五入后为8314337773607070。于是我们重新计算8314337773607070/2^52=1.846153846153846256328279196... 于是小数点后保留16位应该   发表于 2014-10-28 13:18
这个显然同具体实现相关。默认如果是MachinePrecision,15.6位也就是相当于52比特的精度。 所以可以判断出来应该是一位符号位,尾数52位,幂11比特(-1024~1023) 所以相当于C语言里面的double类型  发表于 2014-10-28 13:12
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-10-28 15:10:57 | 显示全部楼层
  1. ToString[N[24/13],InputForm]
复制代码

的输出是 1.8461538461538463,跟楼上的mathe的分析完全一致,我想这样算是彻底回答了楼主的问题了吧
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2014-10-28 17:00:43 | 显示全部楼层
不纠结这个,你想要准确就多保留小数
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2015-7-12 10:50:46 | 显示全部楼层
问题又来了
  1. N[287185629353205/4 - (128433317878965*Sqrt[5])/4]
  2. N[287185629353205/4 - (128433317878965*Sqrt[5])/4, 4]
复制代码

结果是
0.03125
0.03816

  1. N[287185629353205/4 - (128433317878965*Sqrt[5])/4]
复制代码

等于以下结果
  1. N[287185629353205/4] - N[(128433317878965*Sqrt[5])/4]
复制代码


而下面输出很规则。
  1. Do[Print[N[287185629353205/4 - (128433317878965*Sqrt[5])/4, i]], {i,  20}]
复制代码


是否意味着不指定精确度的N不可靠,而且还要故意让Mathematica多算几位再另行处理?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2015-7-14 11:34:28 | 显示全部楼层
zeroieme 发表于 2015-7-12 10:50
是否意味着不指定精确度的N不可靠,而且还要故意让Mathematica多算几位再另行处理?

这个我宁愿看成是Mathematica的bug 。
我担心Mathematica的N函数的内部实现 存在过早优化的问题:

当f,g都比较复杂的时候,Mathematica优化成了: N[f +g ]  =N[f] +N[g]
-------------------------------
有空再深入追究一下
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2015-7-15 15:52:03 | 显示全部楼层
wayne 发表于 2015-7-14 11:34
这个我宁愿看成是Mathematica的bug 。
我担心Mathematica的N函数的内部实现 存在过早优化的问题:


自然是Mathematica的bug 。
作为D版使用者,也不好向Mathematica公司反馈。只能探讨自己写代码时如何绕开这个bug。


BTW wayne能帮忙反馈么
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 01:16 , Processed in 0.030763 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表