Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
已翻译JavaScript中的舍入错误_Javascript_Floating Point_Fortran - Fatal编程技术网

已翻译JavaScript中的舍入错误

已翻译JavaScript中的舍入错误,javascript,floating-point,fortran,Javascript,Floating Point,Fortran,我翻译了一个旧的Fortran程序,它模拟了阻尼驱动的线性振荡器。以下是JS: /*jslint browser: true, devel: true */ /*global VERLET */ /*global FORCE */ /*global $ */ function driven() { "use strict"; //MODULE shared //USE, INTRINSIC :: ISO_FORTRAN_ENV,dp=>REAL64!modern

我翻译了一个旧的Fortran程序,它模拟了阻尼驱动的线性振荡器。以下是JS:

/*jslint browser: true, devel: true */
/*global VERLET */
/*global FORCE */
/*global $ */
function driven() {
  "use strict";
//MODULE shared
  //USE, INTRINSIC :: ISO_FORTRAN_ENV,dp=>REAL64!modern DOUBLE PRECISION
  //INTEGER :: i
  //INTEGER, PARAMETER :: i_max=5000
  //REAL(dp) :: x_read,v_read,const0,gamma,A_o,dt
  //REAL(dp), DIMENSION(:), ALLOCATABLE :: x,v,a,E,dE,time
  //REAL(dp), PARAMETER :: m=1.0
  var i_max,
    i_max_read,
    i,
    x_read,
    v_read,
    const0,
    const0_read,
    gamma,
    gamma_read,
    A_o,
    A_o_read,
    dt,
    dt_read,
    x,
    x_plot,
    v,
    v_plot,
    a,
    a_plot,
    time,
    f_osc,
    sim,
    result,
    nonlinear;
  //i_max = 5000;
  x = [];
  x_plot = [];//new combined array for Flot plotting
  v = [];
  v_plot = [];//new combined array for Flot plotting
  a = [];
  a_plot = [];//new combined array for Flot plotting
  time = [];
  f_osc = [];//unlike Fortran, this needs to be an array
//END MODULE shared

//PROGRAM nonlinear
  nonlinear = document.forms.nonlinear;
  //USE shared
  //IMPLICIT NONE
  //EXTERNAL VERLET
  //ALLOCATE(x(i_max + 1))
  //ALLOCATE(v(i_max + 1))
  //ALLOCATE(a(i_max + 1))
  //ALLOCATE(E(i_max + 1))
  //ALLOCATE(dE(i_max + 1))
  //ALLOCATE(time(i_max + 1))
  //PRINT *, ' '
  //PRINT *, 'Initial position of the mass? [m]'
  //PRINT *, ' '
  //READ *, x_read
  x_read = nonlinear.elements.x_read;
  //x(1) = x_read
  x[0] = parseFloat(x_read.value);
  //PRINT *, ' '
  //PRINT *, 'Initial velocity of the mass? [m/sec]'
  //PRINT *, ' '
  //READ *, v_read
  v_read = nonlinear.elements.v_read;
  //v(1) = v_read
  v[0] = parseFloat(v_read.value);
  //PRINT *, ' '
  //PRINT *, 'Value of k/m? [1/sec^2]'
  //PRINT *, ' '
  //READ *, const0
  const0_read = nonlinear.elements.const0_read;
  const0 = parseFloat(const0_read.value);
  //PRINT *, ' '
  //PRINT *, 'Value of the damping coefficient? [kg/sec]'
  //PRINT *, ' '
  //READ *, gamma
  gamma_read = nonlinear.elements.gamma_read;
  gamma = parseFloat(gamma_read.value);
  //PRINT *, ' '
  //PRINT *, 'Amplitude of the external force? [N]'
  //PRINT *, ' '
  //READ *, A_o
  A_o_read = nonlinear.elements.A_o_read;
  A_o = parseFloat(A_o_read.value);
  i_max_read = nonlinear.elements.i_max_read;
  i_max = parseFloat(i_max_read.value);
  //PRINT *, ' '
  //PRINT *, 'Time-step of the system? [sec]'
  //PRINT *, ' '
  //READ *, dt
  //PRINT *, ' '
  dt_read = nonlinear.elements.dt_read;
  dt = parseFloat(dt_read.value);
  sim = i_max * dt;
  result = sim.toFixed(1);
  document.getElementById('output').innerHTML = result;
  //time(1) = 0.0
  time[0] = 0.0;
  //i = 1
  i = 0;
  //DO
  do {
    //IF(i > i_max) EXIT
    //CALL VERLET
    VERLET(i, x, v, a, time, f_osc, dt, A_o, const0, gamma);
    x_plot[i] = [time[i], x[i]];
    v_plot[i] = [time[i], v[i]];
    a_plot[i] = [time[i], a[i]];
    //time(i + 1) = time(i) + dt
    time[i + 1] = time[i] + dt;
    //i = i + 1
    i = i + 1;
  //END DO
  } while (i < i_max);
  //OPEN(7, file='xt.dat', status='unknown')
  //WRITE(7,'(2f16.6)') (time(i),x(i),i=1,i_max)
  //CLOSE(7)
  //DEALLOCATE(x)
  //DEALLOCATE(v)
  //DEALLOCATE(a)
  //DEALLOCATE(E)
  //DEALLOCATE(dE)
  //DEALLOCATE(time)
  function doPlot(position) {//Flot
    $.plot("#placeholder", [//data
      {
        data: x_plot,
        label: "Position (m)",
        yaxis: 1,
        color: "red"
      },
      {
        data: v_plot,
        label: "Velocity (m/sec)",
        yaxis: 2,
        color: "green"
      },
      {
        data: a_plot,
        label: "Acceleration (m/sec/sec)",
        yaxis: 3,
        color: "blue"
      }
    ],//options
      {
        xaxis: { axisLabel: "Time (sec)" },
        yaxes: [
          { font: { color: "red" } },
          { font: { color: "green" } },
          { font: { color: "blue" } },
          { alignTicksWithAxis: position === "left" ? 1 : null }
        ],
        legend: {
          position: "nw",
          labelBoxBorderColor: null
        }
      }
      );
  }
  doPlot("left");
//END PROGRAM nonlinear
}

//SUBROUTINE VERLET()
function VERLET(i, x_temp, v_temp, a_temp, t_temp, f_osc_temp, dt, A_o, const0, gamma) {
  "use strict";
  //USE shared
  //IMPLICIT NONE
  //REAL(dp) :: x_temp,v_temp,t_temp,f_osc
  //EXTERNAL FORCE,ENERGY
  var m;
  m = 1.0;
  //x_temp = x(i)
  //v_temp = v(i)
  //t_temp = time(i)
  //CALL FORCE(x_temp,v_temp,t_temp,f_osc)
  FORCE(i, x_temp, v_temp, t_temp, f_osc_temp, A_o, const0, gamma);
  //x_temp = x(i)
  //v_temp = v(i)
  //CALL ENERGY!don't think I'm actually using this; no INTENT(OUT)
  //a(i) = f_osc/m
  a_temp[i] = f_osc_temp[i] / m;
  //x(i + 1) = x(i) + v(i)*dt + 0.5*a(i)*dt*dt
  x_temp[i + 1] = x_temp[i] + v_temp[i] * dt + 0.5 * a_temp[i] * dt * dt;
  //x_temp = x(i + 1)
  //v_temp = v(i)
  //t_temp = time(i + 1)
  //CALL FORCE(x_temp,v_temp,t_temp,f_osc)
  FORCE(i, x_temp, v_temp, t_temp, f_osc_temp, A_o, const0, gamma);
  //a(i + 1) = f_osc/m
  a_temp[i + 1] = f_osc_temp[i] / m;
  //v(i + 1) = v(i) + 0.5*(a(i + 1) + a(i))*dt
  v_temp[i + 1] = v_temp[i] + 0.5 * (a_temp[i + 1] + a_temp[i]) * dt;
  //x_temp = x(i + 1)
  //v_temp = v(i + 1)
  //CALL ENERGY!don't think I'm actually using this; no INTENT(OUT)
  return [x_temp, v_temp, a_temp, t_temp];
//END
}

//SUBROUTINE FORCE(xs,vs,ts,f_oscs)
function FORCE(i, xs, vs, ts, f_oscs, A_o, const0, gamma) {
  "use strict";
  //USE shared
  //IMPLICIT NONE
  //REAL(dp), INTENT(IN) :: xs,vs,ts
  //REAL(dp), INTENT(OUT) :: f_oscs
  //REAL(dp) :: f_t
  var f_t;
  //f_t = A_o*DCOS(2.0*ts)
  f_t = A_o * Math.cos(2.0 * ts[i]);
  //f_oscs = -const0*xs - gamma*vs + f_t
  f_oscs[i] = -const0 * xs[i] - gamma * vs[i] + f_t;
  return f_oscs;
//END
}

//SUBROUTINE ENERGY()
  //USE shared
  //IMPLICIT NONE
  //!REAL(dp), INTENT(OUT) ::
  //E(i) = 0.5*(v(i)**2 + const0*x(i)**2)
  //E(1) = 0.5*(v(1)**2 + const0*x(1)**2)
  //dE(i) = E(i) - E(1)
//END
…从翻译后的JavaScript:

    0.000000        0.100000
    0.010000        0.129930
    0.020000        0.159707
    ...
    
结果会变得更糟。经过5000步后,结果相差0.01。我不习惯在JS中使用数组,因此错误可能就在那里的某个地方。这是我第一次遇到这样的事情。有人知道这里发生了什么吗


更新1 JS本身:

/*jslint browser: true, devel: true */
/*global VERLET */
/*global FORCE */
/*global $ */
function driven() {
  "use strict";
  var i_max,
    i_max_read,
    i,
    x_read,
    v_read,
    const0,
    const0_read,
    gamma,
    gamma_read,
    A_o,
    A_o_read,
    dt,
    dt_read,
    x,
    x_plot,
    v,
    v_plot,
    a,
    a_plot,
    time,
    f_osc,
    sim,
    result,
    nonlinear;
  x = [];
  v = [];
  a = [];
  time = [];
  f_osc = [];//unlike Fortran, this needs to be an array
  time[0] = 0.0;
  i = 0;
  do {
    VERLET(i, x, v, a, time, f_osc, dt, A_o, const0, gamma);
    time[i + 1] = time[i] + dt;
    i = i + 1;
  } while (i < i_max);
}

function VERLET(i, x_temp, v_temp, a_temp, t_temp, f_osc_temp, dt, A_o, const0, gamma) {
  "use strict";
  var m;
  m = 1.0;
  FORCE(i, x_temp, v_temp, t_temp, f_osc_temp, A_o, const0, gamma);
  a_temp[i] = f_osc_temp[i] / m;
  x_temp[i + 1] = x_temp[i] + v_temp[i] * dt + 0.5 * a_temp[i] * dt * dt;
  FORCE(i, x_temp, v_temp, t_temp, f_osc_temp, A_o, const0, gamma);
  a_temp[i + 1] = f_osc_temp[i] / m;
  v_temp[i + 1] = v_temp[i] + 0.5 * (a_temp[i + 1] + a_temp[i]) * dt;
  return [x_temp, v_temp, a_temp, t_temp];
}

function FORCE(i, xs, vs, ts, f_oscs, A_o, const0, gamma) {
  "use strict";
  var f_t;
  f_t = A_o * Math.cos(2.0 * ts[i]);
  f_oscs[i] = -const0 * xs[i] - gamma * vs[i] + f_t;
  return f_oscs;
}
/*jslint浏览器:true,devel:true*/
/*全球VERLET*/
/*全球力量*/
/*全球美元*/
函数驱动的(){
“严格使用”;
var i_max,
我读过,
我
x_read,
v_read,
常数0,
康斯特雷德,
伽马,
伽马·雷德,
A_o,
你读到了,
dt,
德图雷德,
x,,
x_图,
v
v_图,
A.
阴谋,
时间
f_osc,
sim卡,
结果,,
非线性;
x=[];
v=[];
a=[];
时间=[];
f_osc=[];//与Fortran不同,它需要是一个数组
时间[0]=0.0;
i=0;
做{
VERLET(i,x,v,a,time,f_osc,dt,a_o,const0,gamma);
时间[i+1]=时间[i]+dt;
i=i+1;
}而(i

更新2 这是一个类似的JS,没有出现这种症状:

/*jslint browser: true, devel: true */
/*global $ */
function amp() {
  "use strict";
  var i_max,
    i,
    m,
    f_osc,
    theta,
    theta_plot,
    omega,
    omega_plot,
    a,
    e,
    e_plot,
    de,
    time,
    theta0,
    read_ratio,
    const0,
    T,
    result,
    omega_read,
    dt_read,
    dt,
    amplitude;
  i_max = 500;
  m = 1.0;
  f_osc = 0.0;
  theta = [];
  omega = [];
  a = [];
  e = [];
  de = [];
  time = [];
  e[0] = 0.5 * (Math.pow(omega[0], 2) + const0 * Math.pow(theta[0], 2));
  time[0] = 0.0;
  i = 0;
  do {
    f_osc = -const0 * Math.sin(theta[i]);
    a[i] = f_osc / m;
    e[i] = 0.5 * (Math.pow(omega[i], 2) + const0 * Math.pow(theta[i], 2));
    de[i] = e[i] - e[0];
    theta[i + 1] = theta[i] + omega[i] * dt + 0.5 * a[i] * dt * dt;
    f_osc = -const0 * Math.sin(theta[i + 1]);
    a[i + 1] = f_osc / m;
    omega[i + 1] = omega[i] + 0.5 * (a[i + 1] + a[i]) * dt;
    e[i] = 0.5 * (Math.pow(omega[i + 1], 2) + const0 * Math.pow(theta[i + 1], 2));
    de[i] = e[i] - e[0];
    time[i + 1] = time[i] + dt;
    i = i + 1;
  } while (i < i_max);
}
/*jslint浏览器:true,devel:true*/
/*全球美元*/
函数amp(){
“严格使用”;
var i_max,
我
M
f_osc,
西塔,
西塔图,
欧米茄,
欧米伽图,
A.
E
e_图,
判定元件,
时间
θ0,
读写比,
常数0,
T
结果,,
欧米伽读,
德图雷德,
dt,
振幅
i_max=500;
m=1.0;
f_osc=0.0;
θ=[];
ω=[];
a=[];
e=[];
de=[];
时间=[];
e[0]=0.5*(数学功率(ω[0],2)+常数0*数学功率(θ[0],2));
时间[0]=0.0;
i=0;
做{
f_osc=-const0*Math.sin(θ[i]);
a[i]=f_osc/m;
e[i]=0.5*(数学功率(ω[i],2)+常数0*数学功率(θ[i],2));
de[i]=e[i]-e[0];
θ[i+1]=θ[i]+ω[i]*dt+0.5*a[i]*dt*dt;
f_osc=-const0*Math.sin(θ[i+1]);
a[i+1]=f_osc/m;
ω[i+1]=ω[i]+0.5*(a[i+1]+a[i])*dt;
e[i]=0.5*(数学功率(ω[i+1],2)+常数0*数学功率(θ[i+1],2));
de[i]=e[i]-e[0];
时间[i+1]=时间[i]+dt;
i=i+1;
}而(i
最大的区别在于,这个函数不包含我认为是子程序的函数。我在这方面做了什么非法的事情吗?

对FORCE()的第二次调用所做的事情与FORTRAN对应的不同

在FORTRAN中,您可以执行以下操作:

a(i) = FORCE( x(i) , v(i) , time(i) ) / m
a(i+1) = FORCE( x(i) + v(i)*dt + 0.5*a(i)*dt*dt , v(i) , time(i+1) ) / m
在JS中,您可以做另一件事:

a(i) = FORCE( x(i) , v(i) , time(i) ) / m
a(i+1) = FORCE( x(i) , v(i) , time(i) ) / m
由于FORTRAN a(i+1)的中间结果将需要混合x(i+1)和v(i) 因此,仅将i作为参数传递听起来不太合适
您可以设置v[i+1]=v[i]并尝试一个力(i+1,…),但这听起来太棘手了


要么坚持更接近的翻译,要么尝试完全重写。

我相信您遇到了浮点精度问题()。我建议使用一个库来纠正这个问题,比如BigDecimal端口()。Fortran数字的数据类型是什么?Javascript使用具有11位指数和52位尾数的双精度浮点数(double)。通常认为双工对物理模拟来说已经足够好了。我在生活中见过很多东西,但你是第一个将Fortran 2008代码称为“旧Fortran程序”的人。我想我更愿意将代码分开,因为很难按照你的方式来处理。(最好去掉与绘图等相关的无关内容)在时间
0.02
的第五个有效数字中,代码之间存在差异
2
。我不认为这仅仅是浮点运算性质的结果,它在我看来更像是一个错误。我看到您在Javascript中编写了
使用strict
。我想这意味着严格遵守IEEE754浮点运算?如果是这样,您是否以同样的严格程度编译Fortran?大多数Fortran编译器在默认情况下不会这样做,因为它会减慢速度。最大的问题是,我只是不太习惯在JS中使用函数/子例程。坚持直译,移动
time[i+1]=time[i]+dt到之前
t_temp=时间[i+1](新发现的逻辑问题),问题已解决。谢谢你的帮助!
a(i) = FORCE( x(i) , v(i) , time(i) ) / m
a(i+1) = FORCE( x(i) , v(i) , time(i) ) / m