首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将浮点数除以自身会产生非常大的整数

将浮点数除以自身会产生非常大的整数
EN

Stack Overflow用户
提问于 2012-02-01 19:17:10
回答 2查看 321关注 0票数 3

所以我遇到了一个在我看来非常奇怪的问题。我有一个在2D平面上对物体施加力的粗糙系统,其中一个最简单的计算似乎会导致我的一个变量溢出。我有下面这行代码:

int ySign = m_Momentum.y / abs(m_Momentum.y);

其中Momentum有两个数据成员,x y (m_Momentum是浮点数的SFML sf::Vector2 )。现在,通常公式应该总是返回1或-1,这取决于Momentum.y的符号(除非我大错特错)。

但是,它偶尔会返回非常高的数字,比如-2147483648。在那个特定的例子中,m_Momentum.y的值是0.712165 (这两个值都是通过发送到std::cout获得的);我再次尝试,m_Momentum.y是-0.578988,而ySign仍然是-0.578988。有一个相应的xSign有时也会翻转,通常具有相同的最终值。我不能百分之百地确认这总是结果,但目前看来是这样的。

我有点困惑于为什么会发生这种情况,当它发生时,它基本上会使我的程序失效(它会立即向对象发送数百万像素的错误方向)。上面这行代码返回如此奇怪的结果在逻辑上似乎是不可能的。

下面是我正在处理的函数。也许这样做是错误的,但我没想到会出这么大的差错。它产生的打印输出显示,在打印出符号之前,所有数字看起来都是正常的;其中一个总是很大,之后您会看到像-2.727e+008这样的数字(据我所知,这是科学记数法-即-2.727 *10^8)。

代码语言:javascript
复制
///MODIFY MOMENTUM
//Reset, if necessary
if (Reset == true)
{
    m_Momentum.x = 0;
    m_Momentum.y = 0;
}
sf::Vector2<float> OldMoment = m_Momentum;

//Apply the force to the new momentum.
m_Momentum.x += Force.x;
m_Momentum.y += Force.y;
sf::Vector2<float> NewMoment = m_Momentum;

//Calculate total momentum.
float sqMomentum = m_Momentum.x * m_Momentum.x + m_Momentum.y * m_Momentum.y;
float tMomentum = sqrt(sqMomentum);

//Preserve signs for later use.
int xSign = m_Momentum.x / abs(m_Momentum.x);
int ySign = m_Momentum.y / abs(m_Momentum.y);

//Determine more or less the ratio of importance between x and y components
float xProp;
float yProp;
if (abs(tMomentum) > m_MaxVelocity)
{
    //Get square of maximum velocity
    int sqMax = m_MaxVelocity * m_MaxVelocity;
    //Get proportion of contribution of each direction to velocity
    xProp = (m_Momentum.x * m_Momentum.x) / sqMomentum;
    yProp = (m_Momentum.y * m_Momentum.y) / sqMomentum;
    //Reset such that the total does not exceed maximum velocity.
    m_Momentum.x = sqrt(sqMax * xProp) * xSign;
    m_Momentum.y = sqrt(sqMax * yProp) * ySign;
}

///SANITY CHECK
//Preserve old tMomentum
float tOld = tMomentum;

//Calculate current tMomentum
sqMomentum = m_Momentum.x * m_Momentum.x + m_Momentum.y * m_Momentum.y;
tMomentum = sqrt(sqMomentum);

//If it's still too high, print a report.
if (tMomentum > m_MaxVelocity)
{
    std::cout << "\n\nSANITY CHECK FAILED\n";
    std::cout << "-\n";
    std::cout << "Old Components: " << OldMoment.x << ", " << OldMoment.y << "\n";
    std::cout << "Force Components: " << Force.x << ", " << Force.y << "\n";
    std::cout << "-\n";
    std::cout << "New Components: " << NewMoment.x << ", " << NewMoment.y << "\n";
    std::cout << "Which lead to...\n";
    std::cout << "tMomentum: " << tOld << "\n";
    std::cout << "-\n";
    std::cout << "Found these proportions: " << xProp << ", " << yProp << "\n";
    std::cout << "Using these signs: " << xSign << ", " << ySign << "\n";
    std::cout << "New Components: " << m_Momentum.x << ", " << m_Momentum.y << "\n";
    std::cout << "-\n";
    std::cout << "Current Pos: " << m_RealPosition.x << ", " << m_RealPosition.y << "\n";
    std::cout << "New Pos: " << m_RealPosition.x + m_Momentum.x << ", " << m_RealPosition.y + m_Momentum.y << "\n";
    std::cout << "\n\n";
}

///APPLY FORCE
//To the object's position.
m_RealPosition.x += m_Momentum.x;
m_RealPosition.y += m_Momentum.y;

//To the sprite's position.
m_Sprite.Move(m_Momentum.x, m_Momentum.y);

有人能解释一下这是怎么回事吗?

编辑: RedX帮助我访问了以下帖子:Is there a standard sign function (signum, sgn) in C/C++?,这使我编写了以下代码行:

代码语言:javascript
复制
//Preserve signs for later use.
//int xSign = m_Momentum.x / abs(m_Momentum.x);
//int ySign = m_Momentum.y / abs(m_Momentum.y);
int xSign = (m_Momentum.x > 0) - (m_Momentum.x < 0);
int ySign = (m_Momentum.y > 0) - (m_Momentum.y < 0);

多亏了以上,我不再有奇怪的问题了。有关解释/替代解决方案,请参阅下面Didier的帖子。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-01 19:23:26

应该使用fabs()而不是abs()来获取浮点数的绝对值。如果使用integer绝对值函数,则结果是一个整数...

例如,-0.5 / abs(-0.5)被视为-0.5 / 0,它导致负无穷大(作为浮点值)被转换为int 0x80000000 = -2147483648的最小值

票数 8
EN

Stack Overflow用户

发布于 2012-02-03 10:22:49

对我来说,取绝对值和除法听起来像是在浪费周期。有什么问题吗

代码语言:javascript
复制
x > 0 ? 1 : -1

你总是可以把它放在一个函数中

代码语言:javascript
复制
template <class T>
inline int sgn(const T &x) { return x > 0 ? : 1; }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9094868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档