Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Floating point arithmetic strange results

Status
Not open for further replies.

titanzero

Programmer
May 3, 2007
30
EU
Hello everyone

I have a strange problem with floating points

This is keep track of x and y coords and change them randomly when reqested.
Code:
#include <RandGen.hpp>

using namespace std;

#ifndef _POINT_HPP_	//Check if this file has been included or not
#define _POINT_HPP_	//It has not so include and define
class Point
{
	public:
		~Point();
		Point();
		void init(float theX, float theY);
		void setX(float theX);
		void setY(float theY);
		float getX();
		float getY();
		void move();
		float startX;
		float startY;
	private:
		float x;
		float y;
		RandGen *prg;
};

Point::Point()
{
	prg = new RandGen(1,4);
	x = 0.0f;
	y = 0.0f;
	startX = 0.0f;
	startY = 0.0f;
}

Point::~Point()
{
	if(prg)
		delete prg;
}

void Point::init(float theX, float theY)
{
	startX = theX;
	startY = theY;
	x = startX;
	y = startY;
}
void Point::setX(float theX)
{
	x = theX;
}

void Point::setY(float theY)
{
	y = theY;
}

float Point::getX()
{
	return x;
}

float Point::getY()
{
	return y;
}

void Point::move()
{
	//Select a random direction and set x and y accordingly
	int dir = prg->nextRandInRange();

	if(dir == 1)	//north
		y = y + 0.1f;
	else if(dir == 2)	//east
		x = x + 0.1f;
	else if(dir == 3)	//south
		y = y - 0.1f;
	else if(dir ==4)	//west
		x = x - 0.1f;
	else
		cout << endl << "Epic fail";
}
#endif

This just loops a load of times telling the point to move
Code:
#include<iostream>
#include<Point.hpp>

using namespace std;

int main()
{
	Point *p = new Point();
	p->init(0.0f,0.0f);

	for(int i = 0; i < 10000; i++)
	{
		p->move();
		cout << endl << p->getX();
		cout << endl << p->getY();
	}

	cout << endl << endl << "END OF PROG" << endl;
	return 0;
}

This code will produce unexpected results like 0.1 - 0.1 = 1.49012e008. It only does it some times. I can recreate the problem in a simple example by not putting an 'f' after I declare some var (e.g. float myFloat = 0.1;). However I cant see this problem in my code. Maybe I've been looking at it to long but I am sure I initiate all my floats and I am sure I put 'f' to indicate that its a float.

Does anyone have any ideas?

Thank you for your time
Andrew
 
32 bit floats are only accurate to 6 significant figures (not decimal places). If you want 10, try 64 bit doubles. Don't expect anything to make sense after the 6th figure if you're using a float.

0.1 - 0.1 = 1E-8 is OK since it is 1E-1 - 1E-1 = 1E-8. 1+6=7 so it was accurate to 6 figures. The 7th one should be ignored and is normally a load of rubbish.
 
thanks xwb. I changed to double and got the results i expected. Thanks for your time you amazing person. :)
 
erm...it did not fix the problem. It only appeared to fix the problem. Again I am confused as to why -0.1 + 0.1 = anything other than 0. Like wise 0.1 - 0.1 should in my mind always = 0. Why am I getting results that are not 0? And why does this only occure some times? Some times in my code a caluclation like 0.1 - 0.1 does equal 0 and sometimes its greater than 1? Any insight?

Thanks again for your time
Andrew
PS you are still amazing lol
 
titanzero,

Because of the way floating point numbers are represented by the computer there can be inconsistencies when comparing two numbers that appear to be identical. Unlike integers, IEEE floating point numbers are only approximates, not exact numbers. The need to convert the numbers to a form the computer can store in binary leads to minor precision or round-off deviations. For example 1.3 may really be represented as 1.29999999999.
That's why you can never compare 2 floats. what you can do is substract them and then test for the precision you want.

something like abs(f1-f2) < 0.0001 (0.0001 is the "deviation" or precision in this case)

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
The deviations can be found float.h

FLT_EPSILON for floats
DBL_EPSILON for doubles

Look for "floating limits" in Visual Studio Help

 
Of course, a floating point constant 0.1 is equal to the same constant 0.1 in C++, but the point is that 0.01*10.0 is not equal to 0.1 exactly ;)

Moreover, floating point constant 0.1 in your program source is not equal to 0.1 from input streams in some implementations.

Be careful, read more about floating point data types (in Wikipedia, for example).
 
Thanks everyone for your help. Now I know that floats can be messy I wrote a simple function to round my numbers to 1 decimal place. I now get the results I expect. Thanks again people you are all amazing.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top