gpt4 book ai didi

c++ - 将 float 本身除以产生非常大的整数

转载 作者:太空狗 更新时间:2023-10-29 20:06:11 28 4
gpt4 key购买 nike

所以我遇到了一个在我看来非常奇怪的问题。我有一个用于对 2D 平面上的对象施加力的粗略系统,最简单的计算之一似乎导致我的一个变量溢出。我有以下行:

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

其中 Momentum 有两个数据成员,x y(m_Momentum 是一个 SFML sf::Vector2 float )。现在,通常公式应始终返回 1 或 -1,具体取决于 Momentum.y 的符号(除非我严重误会)。

但是,它有时会返回异常高的数字,例如 -2147483648。在那种特殊情况下,m_Momentum.y 的值为 0.712165(这两个值都是通过发送到 std::cout 获得的);我再次尝试,m_Momentum.y 为 -0.578988,ySign 仍为 -2147483648。有一个相应的 xSign 有时也会翻转,通常具有相同的最终值。我无法 100% 确定结果总是如此,但目前看来确实如此。

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

下面是我正在处理的功能。可能做错了方法,但我没想到会错得这么可怕。它产生的打印输出表明,在打印出符号之前,所有数字看起来都很正常;其中一个总是很大,之后你会看到像 -2.727e+008 这样的数字(据我所知,这是科学记数法 - 即 -2.727 * 10 ^ 8)。

///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++?这促使我编写了以下代码行:

//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 的帖子。

最佳答案

您应该使用 fabs() 而不是 abs() 来获取 float 的绝对值。如果使用整数绝对函数,那么结果是一个整数...

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

的最小值

关于c++ - 将 float 本身除以产生非常大的整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9094868/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com