.01f != 0.0099999998 !!!!!!!!!!

Started by
44 comments, last by Ravyne 16 years, 11 months ago
I am setting a float to 0.01f but it immediately gets the value of 0.009999999998! Any insight on the loss of precision of something that only has a hundredth of a decimal place? Brandon
Advertisement
Yep, plenty! Read this. It will make you a better coder.
made it a double, its fixed.
Floating point numbers are not exact. The float datatype in C and C++ has about 7 significant digits meaning that 0.01f could also be equal to any value in the interval (0.009999998, 0.01000001). This is what you're seeing.
Quote:

The IEEE standard goes further than just requiring the use of a guard digit. It gives an algorithm for addition, subtraction, multiplication, division and square root, and requires that implementations produce the same result as that algorithm. Thus, when a program is moved from one machine to another, the results of the basic operations will be the same in every bit if both machines support the IEEE standard. This greatly simplifies the porting of programs. Other uses of this precise specification are given in Exactly Rounded Operations.


Reading this leads me to believe that using floating point *is* safe for networked games that must be in sync each frame. Am I wrong here?
Quote:Original post by Daniel Miller
Quote:

The IEEE standard goes further than just requiring the use of a guard digit. It gives an algorithm for addition, subtraction, multiplication, division and square root, and requires that implementations produce the same result as that algorithm. Thus, when a program is moved from one machine to another, the results of the basic operations will be the same in every bit if both machines support the IEEE standard. This greatly simplifies the porting of programs. Other uses of this precise specification are given in Exactly Rounded Operations.


Reading this leads me to believe that using floating point *is* safe for networked games that must be in sync each frame. Am I wrong here?

Yes, I've mentioned this in my most recent journal posting, but if you were to have one of your clients using SSE instruction sets, and another using the FPU, you can easily obtain results that differ in the least significant digits. This is due to a difference in the size of the registers used to calculate the numbers (32 bit float is widened to 80 bit on FPU, while it remains at 32 in the XMM registers).

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

solution: Fixed Point.
JRA GameDev Website//Bad Maniac
Quote:Original post by Washu
Quote:Original post by Daniel Miller
Quote:

The IEEE standard goes further than just requiring the use of a guard digit. It gives an algorithm for addition, subtraction, multiplication, division and square root, and requires that implementations produce the same result as that algorithm. Thus, when a program is moved from one machine to another, the results of the basic operations will be the same in every bit if both machines support the IEEE standard. This greatly simplifies the porting of programs. Other uses of this precise specification are given in Exactly Rounded Operations.


Reading this leads me to believe that using floating point *is* safe for networked games that must be in sync each frame. Am I wrong here?

Yes, I've mentioned this in my most recent journal posting, but if you were to have one of your clients using SSE instruction sets, and another using the FPU, you can easily obtain results that differ in the least significant digits. This is due to a difference in the size of the registers used to calculate the numbers (32 bit float is widened to 80 bit on FPU, while it remains at 32 in the XMM registers).


Since I'm a noob and have no idea how to do that, would that happen by itself? Or do I have to explicitly use SSE?
Quote:Original post by Daniel Miller
Quote:Original post by Washu
Yes, I've mentioned this in my most recent journal posting, but if you were to have one of your clients using SSE instruction sets, and another using the FPU, you can easily obtain results that differ in the least significant digits. This is due to a difference in the size of the registers used to calculate the numbers (32 bit float is widened to 80 bit on FPU, while it remains at 32 in the XMM registers).


Since I'm a noob and have no idea how to do that, would that happen by itself? Or do I have to explicitly use SSE?

If you enable SIMD instruction sets, it can happen by itself. One common case where you might find this happening would be an optimized math library that changes its behavior based on the instruction sets available on the client PC.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Quote:Original post by Washu
Quote:Original post by Daniel Miller
Quote:Original post by Washu
Yes, I've mentioned this in my most recent journal posting, but if you were to have one of your clients using SSE instruction sets, and another using the FPU, you can easily obtain results that differ in the least significant digits. This is due to a difference in the size of the registers used to calculate the numbers (32 bit float is widened to 80 bit on FPU, while it remains at 32 in the XMM registers).


Since I'm a noob and have no idea how to do that, would that happen by itself? Or do I have to explicitly use SSE?

If you enable SIMD instruction sets, it can happen by itself. One common case where you might find this happening would be an optimized math library that changes its behavior based on the instruction sets available on the client PC.


I am using DirectX/C#. Would that happen by itself (I wouldn't be using any 3D math, this is a 2D game)? Thanks a bunch for your insight.

EDIT: punctuation
EDIT: spelling 'punctuation'

This topic is closed to new replies.

Advertisement