我编写了一个程序,该程序使用事件驱动算法模拟一维完美的弹性碰撞。问题出在牛顿的摇篮上。
我试图修复一个我认为是问题的东西,那就是当我赋予两个球体相等的初始速度时,由于同时发生碰撞,位置和速度阵列会更新两次(因此,对于同一时刻)。
为此,我创建了一个变量,该变量将检查下一次碰撞是否会在0秒内发生(即:“现在”)。但是,当我这样做时,对于那些同时发生的碰撞,直到碰撞完全改变的时间。
总共有5个粒子,每个粒子的半径为1,它们之间的间隔为0.5。碰撞具有完全的弹性,可以忽略重力,并且当最终粒子撞击任意放置在其前面的墙时,该算法就会停止。
前两个粒子的初始速度为1,因此第一次碰撞应在0.5之后发生,第二次和第三次碰撞应在另一个0.5之后同时发生。
在添加变量以检查直到碰撞的时间是否为0之前,将直到碰撞的时间输出为6.94906e-310(这通过输出计算到碰撞的时间的函数的返回值来验证)。
使用要用于检查先前值是否为零的新变量,现在在新变量和上述函数的返回值中,在同时发生碰撞期间发生碰撞之前的时间现在为-1。
我猜想这与一个很小的double值有关,但是我不太理解这个问题。创建一个变量如何在此程度上影响另一个(尽管有些相关)变量的值?
下面的代码仅用于帮助可视化问题。 这不是MWE 。我必须在这里发布几乎所有的代码才能生成MWE。因为这是一堂课,所以我自己可能会被窃或被指控为窃,因此张贴此贴令我感到不舒服。
同样,不是MWE,只是为了更好地解释我在做什么。
//x and v are arrays with the positions and
//velocities, respectively, of each particle
//hasReachedWall(x) checks if the last particle has hit the wall
while (!hasReachedWall(x)) {
//The return value of updatePos(x, v) is a double with the time until the next collision
//aux, is the cause of the problem. Its existence somehow changes
//the return value into -1 when it should be near-zero. Without this variable,
//the return value is as expected (near-zero)
double aux = updatePos(x, v);
cout << aux << endl;
//t is also a double
t += aux;
}
编辑:我知道双精度如何在内部存储,并且对它们执行的操作有错误。我的问题是仅仅创建一个中间变量会完全改变操作的结果。
我正在创建一个double来存储函数的返回值(另一个double-不是 long double,只是double),并且该函数的返回值会发生根本变化。我不明白为什么。