Добрый день,
Я получил свой проект для сборки в режиме выпуска с Microsoft Visual C ++ 2008 Express Edition. Однако некоторые из моих значений с плавающей запятой здесь отличаются от значений в конфигурации отладки. По какой-то причине все они оказываются NaN или нулем для какой-то конкретной функциональности. Я не уверен, почему это происходит, и я впервые строю в режиме релиза, любая помощь приветствуется!
Предпринятые шаги:
Параметры командной строки с плавающей точкой.
Пошаговое выполнение кода не сработало по нескольким причинам.
Часы пялиться на код
Спасибо за чтение!
Вот код неправильного поведения (Примечание: у меня были проблемы с NaNs с этой конкретной функциональностью в прошлом,
однако это просто странно)
/*
This file is part of White - Storm: Lightning (alpha).
Copyright 2012 Christopher Augustus Greeley
White - Storm: Lightning (alpha) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
White - Storm: Lightning (alpha) is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with White - Storm: Lightning (alpha). If not, see <http://www.gnu.org/licenses/>.
*/
#include "Vector Calculator.h"WSL::Math::Vector::VectorCalculator::VectorCalculator()
{
WSL::Containers::Base::XYZ temp;
default_ = temp;
}
WSL::Containers::Base::XYZ WSL::Math::Vector::VectorCalculator::VectorCalculation( WSL::Containers::Base::XYZ goTo, WSL::Containers::Base::XYZ position, float speed, bool td )
{
//Make sure that the vector doesent have any stray values lying around.//
vector = default_;
//Calculate Magnitude.//
x = goTo.getX() - position.getX();
y = goTo.getY() - position.getY();
z = goTo.getZ() - position.getZ();
if( td == true )
magnitude = magn.DotProduct( x, y, z, magnitude );
else
magnitude = magn.DotProduct( x, y, magnitude );
if( x == 0 && y == 0 && z == 0 )
return vector;
//Normilise//
magnitude = sqrt( magnitude );
//Make sure we do not divide by zero.//
if( magnitude != 0 )
{
if( x != 0 )
x /= magnitude;
if( y != 0 )
y /= magnitude;
if( td == true )
if( z != 0 )
z /= magnitude;
}
//Go The Desired Speed.//
if( speed >=0 )
{
x *= speed;
y *= speed;
}
if( td == true )
z *= speed;
vector.setX( x );
vector.setY( y );
vector.setZ( z );
return vector;
}
inline float WSL::Math::Formulas::Dot::DotProduct( float x, float y, float mag )
{
return ( mag = ( ( x ) * ( x ) + ( y ) * ( y ) ) );
}
inline float WSL::Math::Formulas::Dot::DotProduct( float x, float y, float z, float mag )
{
return ( mag = ( ( x ) * ( x ) + ( y ) * ( y ) + ( z ) * ( z ) ) );
}
Заголовок:
/*
This file is part of White - Storm: Lightning (alpha).
Copyright 2012 Christopher Augustus Greeley
White - Storm: Lightning (alpha) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
White - Storm: Lightning (alpha) is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with White - Storm: Lightning (alpha). If not, see <http://www.gnu.org/licenses/>.
*/
#include "Int Bool.h"namespace WSL
{
namespace Math
{
namespace Formulas
{
class Dot
{
public:
inline float DotProduct( float x, float y, float mag );
inline float DotProduct( float x, float y, float z, float mag );
};
}
namespace Vector
{
struct VectorCalculator
{
VectorCalculator();
WSL::Containers::Base::XYZ VectorCalculation( WSL::Containers::Base::XYZ goTo, WSL::Containers::Base::XYZ position, float speed, bool td );
WSL::Containers::Base::XYZ VectorCalculation( WSL::Containers::Base::XYZ goTo, WSL::Containers::Base::XYZ *position, float speed, bool td );
private:
WSL::Containers::Base::XYZ vector;
WSL::Containers::Base::XYZ default_;
float x, y, z, magnitude;
Math::Formulas::Dot magn;
};
}
}
}
Для контекста:
/*
This file is part of White - Storm: Lightning (alpha).
Copyright 2012 Christopher Augustus Greeley
White - Storm: Lightning (alpha) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
White - Storm: Lightning (alpha) is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with White - Storm: Lightning (alpha). If not, see <http://www.gnu.org/licenses/>.
*/
#include "Include.h"namespace WSL
{
namespace Containers
{
namespace Base
{
struct XYZB
{
inline float getX() { return X; }
inline float getY() { return Y; }
inline float getZ() { return Z; }
inline void setX( float Value ) { X = Value; }
inline void setY( float Value ) { Y = Value; }
inline void setZ( float Value ) { Z = Value; }
protected:
float X, Y, Z;
};
struct XYZ : public XYZB
{
public:
XYZ( float x, float y, float z )
{
X = x;
Y = y;
Z = z;
}
inline XYZ() { X = 0; Y = 0; Z = 0; }
};
}
}
}
Проблема была замечена с этими файлами:
/*
This file is part of White - Storm: Lightning (alpha).
Copyright 2012 Christopher Augustus Greeley
White - Storm: Lightning (alpha) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
White - Storm: Lightning (alpha) is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with White - Storm: Lightning (alpha). If not, see <http://www.gnu.org/licenses/>.
*/
#include "Vector.h"WSL::Containers::Math::Vector::Vector()
{
destinationInitialize = false;
threeDimentional = false;
}
WSL::Containers::Math::Vector::Vector( WSL::Containers::Base::XYZ position_ )
{
position = position_;
destinationInitialize = false;
threeDimentional = false;
}
WSL::Containers::Math::Vector::Vector( WSL::Containers::Base::XYZ position_, bool threeDimentional_ )
{
position = position_;
destinationInitialize = false;
threeDimentional = threeDimentional_;
}
float WSL::Containers::Math::Vector::GetDestinationX()
{
return destination.getX();
}
float WSL::Containers::Math::Vector::GetDestinationY()
{
return destination.getY();
}
float WSL::Containers::Math::Vector::GetDestinationZ()
{
return destination.getZ();
}
WSL::Containers::Base::XYZ WSL::Containers::Math::Vector::GetDestination()
{
return destination;
}
WSL::Containers::Base::XYZ WSL::Containers::Math::Vector::GetPosition()
{
return position;
}
float WSL::Containers::Math::Vector::GetX()
{
return position.getX();
}
float WSL::Containers::Math::Vector::GetY()
{
return position.getY();
}
float WSL::Containers::Math::Vector::GetZ()
{
return position.getZ();
}
void WSL::Containers::Math::Vector::SetThreeDimentional( bool value )
{
threeDimentional = value;
}
bool WSL::Containers::Math::Vector::GetThreeDimentional()
{
return threeDimentional;
}
void WSL::Containers::Math::Vector::CalculateVector()
{
vector = vectorCalculator.VectorCalculation( destination, position, speed, threeDimentional );
}
void WSL::Containers::Math::Vector::Move()
{
position.setX( position.getX() + vector.getX() );
position.setY( position.getY() + vector.getY() );
position.setZ( position.getZ() + vector.getZ() );
}
void WSL::Containers::Math::Vector::SetPosition( WSL::Containers::Base::XYZ position_ )
{
position = position_;
}
void WSL::Containers::Math::Vector::SetSpeed( float speed_ )
{
speed = speed_;
}
void WSL::Containers::Math::Vector::SetDestination( float x, float y )
{
destination.setX( x );
destination.setY( y );
if( destinationInitialize == false )
{
destinationInitialize = true;
destination.setZ( 0 );
}
}
void WSL::Containers::Math::Vector::SetDestination( float x, float y, float z )
{
destination.setX( x );
destination.setY( y );
destination.setZ( z );
}
void WSL::Containers::Math::Vector::SetDestination( WSL::Containers::Base::XYZ destination_ )
{
destination = destination_;
}
void WSL::Containers::Math::Vector::SetDestination( float allCoords )
{
destination.setX( allCoords );
destination.setY( allCoords );
destination.setZ( allCoords );
}
void WSL::Containers::Math::Vector::SetVector( WSL::Containers::Base::XYZ vector_ )
{
vector = vector_;
}
WSL::Containers::Base::XYZ WSL::Containers::Math::Vector::GetVector()
{
return vector;
}
float WSL::Containers::Math::Vector::GetSpeed()
{
return speed;
}
Заголовок:
/*
This file is part of White - Storm: Lightning (alpha).
Copyright 2012 Christopher Augustus Greeley
White - Storm: Lightning (alpha) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
White - Storm: Lightning (alpha) is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with White - Storm: Lightning (alpha). If not, see <http://www.gnu.org/licenses/>.
*/
#include "Engine.h"namespace WSL
{
namespace Containers
{
namespace Math
{
class Vector
{
WSL::Math::Vector::VectorCalculator vectorCalculator;
WSL::Containers::Base::XYZ position;
WSL::Containers::Base::XYZ destination;
WSL::Containers::Base::XYZ vector;
bool destinationInitialize, threeDimentional;
float speed;
public:
Vector();
Vector( WSL::Containers::Base::XYZ position_ );
Vector( WSL::Containers::Base::XYZ position_, bool threeDimentional_ );
void CalculateVector();
bool GetThreeDimentional();
void Move();
void SetPosition( WSL::Containers::Base::XYZ position_ );
void SetDestination( float x, float y );
void SetDestination( float x, float y, float z );
void SetDestination( WSL::Containers::Base::XYZ destination_ );
void SetDestination( float allCoords );
void SetSpeed( float speed_ );
void SetThreeDimentional( bool value );
void SetVector( WSL::Containers::Base::XYZ vector_ );
float GetDestinationX();
float GetDestinationY();
float GetDestinationZ();
WSL::Containers::Base::XYZ GetDestination();
WSL::Containers::Base::XYZ GetPosition();
WSL::Containers::Base::XYZ GetVector();
float GetX();
float GetY();
float GetZ();
float GetSpeed();
};
}
}
}
ХОРОШО. Поэтому, как я писал в комментариях, я не знаю ответа на вашу проблему, но, возможно, я смогу предоставить некоторые указатели, которые могут помочь вам найти проблему.
Моим первым предложением было бы вынуть ваш код из контекста lua и выполнить небольшой модульный тест для его отладки. Если при модульном тестировании в режиме выпуска ошибок нет, значит, проблема в другом месте. Если все еще есть ошибки, вы можете найти, если у вас есть ошибка в вашем коде. Если вы уверены, что в вашем коде нет ошибки, вот несколько указателей
По моему опыту, когда встречаются NaN, Zeros или INF, где ничего не ожидается, и нет проблем с вводом или вычислениями, тогда вы можете проверить, изменяет ли вы или какая-либо из используемых вами библиотек флаги с плавающей запятой каким-либо образом ( В окнах вы используете controlfp или control87 для этого, с GCC у вас есть макросы FPU_SETCW FPU_GETCW) Также несоответствие флагов компиляции, которые изменяют способ вычисления с плавающей запятой, может вызвать такие проблемы. Убедитесь, что все библиотеки скомпилированы с использованием одинаковых флагов с плавающей запятой.
Вы также можете изменить способ проверки того, что mag не равно нулю. Вы всегда можете столкнуться с проблемами со значениями с плавающей запятой около нуля. Если вы не знаете статью Брюса Доусона о сравнении поплавков, вот ссылка на последнюю версию: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
Если ничего из этого не помогает, вы, вероятно, передаете неверный номер из LUA.
Других решений пока нет …