中华农历论坛知识讨论区历法知识 → [讨论]JavaScript的算术运算还真有点奇怪


  共有20728人关注过本帖树形打印

主题:[讨论]JavaScript的算术运算还真有点奇怪

帅哥哟,离线,有人找我吗?
秦汉昌
  1楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
[讨论]JavaScript的算术运算还真有点奇怪  发帖心情 Post By:2011/6/19 21:32:00

function XL0_calc(xt,zn,t,n){ //xt星体,zn坐标号,t儒略世纪数,n计算项数
  t/=10; //转为儒略千年数
  var i,j,v=0,tn=1,c;
  var F=XL0[xt],n1,n2,N;
  var n0, pn=zn*6+1, N0 = F[pn+1]-F[pn]; //N0序列总数
  for(i=0;i<6;i++,tn*=t){
    n1=F[pn+i], n2=F[pn+1+i], n0=n2-n1;
    if(!n0) continue;
    if(n<0) N=n2;  //确定项数
    else { N = int2(3*n*n0/N0+0.5)+n1;  if(i) N+=3;  if(N > n2) N=n2; }
    for(j=n1,c=0;j<N;j+=3) c += F[j]*Math.cos(F[j+1] +t*F[j+2]);
    v += c*tn;
  }
  v/=F[0];
  if(xt==0){ //地球
    var t2=t*t, t3=t2*t; //千年数的各次方
    if(zn==0) v += (-0.0728 -2.7702*t -1.1019*t2 -0.0996*t3) / rad;
    if(zn==1) v += (+0.0000 +0.0004*t +0.0004*t2 -0.0026*t3) / rad;
    if(zn==2) v += (-0.0020 +0.0044*t +0.0213*t2 -0.0250*t3) / 1000000;
  }else{ //其它行星
    var dv = XL0_xzb[ (xt-1)*3+zn ];
    if(zn==0) v += -3*t/rad;
    if(zn==2) v += dv/1000000;
    else      v += dv/rad;
  }
  return v;
}

 

我计算  XL0_calc(1,0,1.114532,10)

当计算到    v/=F[0];  的上一行时  v=2912419233242.7744  经验证,结果 正确

 

再往下算,由于 F[0]=1000000000,所以   v/=F[0]  =  2912.4192332428  也正确

 

由于 xt=1  zn=0

所以后面的代码中,只需计算   v += -3*t/rad;

 

而t=t/10=1.114532/10=0.1114532   ,-3*t/rad= -0.0000016210

因此,v += -3*t/rad=2912.4192332428  -0.0000016210  = 2912.4192316218

 

从程序的运行规律规律来看,这样计算的答案 应该是正确的

但是,通过运行整个程序,得到的最终结果 却有差异,实际结果为:2912.4192312033106

 

请高人指点迷津


 

 


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  2楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 21:38:00

注: var rad  = 180*3600/Math.PI; //每弧度的角秒数

支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  3楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 21:39:00

这个差异导致结果从第七位小数开始不相同

支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  4楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 21:40:00

从天文计算的角度讲,不知精确到前六位会不会对计算的准确性产生较大影响

支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
浪-淘-沙
  5楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:2068 积分:4263 威望:5 精华:4 注册:2008/11/13 21:03:00
  发帖心情 Post By:2011/6/19 21:49:00

   2912.4192316218

与2912.419231621753

 

有区别吗?四舍五入而已。

 

且有14位有效数字,你还嫌少?


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  6楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 22:11:00

结果为:2912.4192312033106


document.getElementsByTagName是我们接触到的domcument文档对象模型的第二个接口,它的作用通过它的名字很容易理解:它解析文档获取具有指定标记名称的一个列表,在这里document.getElementsByTagName("h1")[0]得到文档中的第一个&1th1>标记。

 

 

测试原码如下:

 

<html>
<head>
<TITLE>寿星天文历</TITLE>
<META c  name=keywords>
<meta http-equiv="Content-Type" c>

<style>
td {font-family:宋体; font-size:12px; line-height:150%}
 .bd0   {border: 0px}
 .bd1   {border: 1px solid #000000}
 .bd2   {border: 2px solid #000000}
 .dTop  {border-top:    1px solid #000000}
 .dBot  {border-bottom: 1px solid #000000}
 .dRig  {border-right:  1px solid #000000}
 .dLef  {border-left:   1px solid #000000}
 .dRB   {border-right: 1 solid #000000;border-bottom: 1 solid #000000}
 .dRT   {border-right: 1 solid #000000;border-top:    1 solid #000000}
 .dBot2 {border-bottom: 1px solid #C0C0C0}
 .dTop2 {border-top:    1px solid #C0C0C0}

</style>
<!--js1S-->
<script language=javascript src=tools.js></script><!--工具函数-->
<script language=javascript src=eph0.js></script> <!--天文常数等-->
<script language=javascript src=ephB.js></script> <!--恒星计算(如果不须要恒星,删除此行)-->
<script language=javascript src=eph.js></script>  <!--星历模块-->
<script language=javascript src=JW.js></script>   <!--全国城市经纬数据库及皇帝纪年数据库-->
<script language=javascript src=lunar.js></script><!--日历物件-->
<script language=javascript src=vml.js></script>  <!--画图物件-->
<script language=javascript src=help.js></script> <!--即时帮助-->
<script language=javascript src=page_gj.js></script> <!--工具页面函数-->
<!--js1E-->

<script type="text/JavaScript">
function PageLoad()
{  var c='a'+'b';
   var b=XL0_calc(1,0,1.114532,10);
   document.getElementsByTagName("h1")[0].innerHTML = ( "结果为:"+b);
}

</script>
</head>
<body >

<h1>
<noscript>您的浏览器不支持JavaScript,请检查浏览器版本或者安全设置,谢谢!</noscript>
</h1>
<hr/>
<p>document.getElementsByTagName是我们接触到的domcument文档对象模型的第二个接口,它的作用通过它的名字很容易理解:它解析文档获取具有指定标记名称的一个列表,在这里document.getElementsByTagName("h1")[0]得到文档中的第一个&1th1&gt标记。</p>
</body>
</html>


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  7楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 22:18:00

以下是引用浪-淘-沙在2011-6-19 21:49:00的发言:

   2912.4192316218

与2912.419231621753

 

有区别吗?四舍五入而已。

 

且有14位有效数字,你还嫌少?

不好意思,我在一楼把许老师的源码实际测试结果弄错了,许老师的代码结果应该是:2912.4192312033106


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  8楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 22:19:00

是从第六位开始,有差异了

支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
浪-淘-沙
  9楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:2068 积分:4263 威望:5 精华:4 注册:2008/11/13 21:03:00
  发帖心情 Post By:2011/6/19 22:24:00

以下是引用秦汉昌在2011-6-19 22:19:00的发言:
是从第六位开始,有差异了

还是看有效数字的。

有10位有效数字,应当也不会影响结果。

 

如果原始数据的有效位数很低,比如只有6位,你计算得到10位数字,意义也不大的。

 

一个程序里的中间量的有效位数,不必太在意。你要看结果与“真值”之间的有多大的差别。


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
帅哥哟,离线,有人找我吗?
秦汉昌
  10楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:业余侠客 帖子:372 积分:1447 威望:0 精华:0 注册:2008/12/20 18:10:00
  发帖心情 Post By:2011/6/19 22:34:00

呵呵,已经有十个有效数字位是正确的了

       呵呵,只要不影响天文计算,我也不想再去深研了


支持(0中立(0反对(0单帖管理 | 引用 | 回复 回到顶部
总数 12 1 2 下一页

返回版面帖子列表

[讨论]JavaScript的算术运算还真有点奇怪








签名