PCSX2 Documentation/What's clamping? And why do we need it?: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 1: Line 1:
{{DocTabs|Section=3}}
''Originally written by cottonvibes''
''Originally written by cottonvibes''


Line 8: Line 7:


Basically there's something called the "The IEEE Standard for Floating-Point Arithmetic" (or IEEE 754), which defines floating point representation; and most systems abide by those rules (of course not our wonderful PS2).
Basically there's something called the "The IEEE Standard for Floating-Point Arithmetic" (or IEEE 754), which defines floating point representation; and most systems abide by those rules (of course not our wonderful PS2).


There's 32-bit "Single Precision Floats" (commonly referred to as 'float'), 64-bit "Double Precision Floats" (commonly referred to as 'double'), and there's even 128-bit floats called Quads (most processors don't support these natively).
There's 32-bit "Single Precision Floats" (commonly referred to as 'float'), 64-bit "Double Precision Floats" (commonly referred to as 'double'), and there's even 128-bit floats called Quads (most processors don't support these natively).
Line 14: Line 12:
The one we're concerned about is the Single Precision Float, which is 32bits and has a format like this
The one we're concerned about is the Single Precision Float, which is 32bits and has a format like this


S x 1bit | E x 8bits | M x 23bits
<code>S x 1bit | E x 8bits | M x 23bits</code>


S = Sign Bit (0 = Positive Number; 1 = Negative Number)
S = Sign Bit (0 = Positive Number; 1 = Negative Number)
Line 34: Line 32:


Example:
Example:
<source lang="text">
NaN + 500 = NaN (generally the same NaN, since it propagates)
NaN + 500 = NaN (generally the same NaN, since it propagates)
INF - 19999999999 = INF
INF - 19999999999 = INF
</source>


This is how the IEEE 754 standard defined this stuff (I honestly don't like it, but w/e)
This is how the IEEE 754 standard defined this stuff (I honestly don't like it, but w/e)
Line 44: Line 44:
For comparison of what your x86-32 CPU does VS the ps2 we have:
For comparison of what your x86-32 CPU does VS the ps2 we have:


Your PC:
'''Your PC:'''
<source lang="cpp">
1/0 = NaN
1/0 = NaN
sqrt (-4) = NaN
sqrt (-4) = NaN
INF - 1000 = INF
INF - 1000 = INF
</source>


The PS2:
'''The PS2:'''
<source lang="cpp">
1/0 = Greatest Positive Float Number (0x7ffffffff)
1/0 = Greatest Positive Float Number (0x7ffffffff)
sqrt (-4) = sqrt(abs(-4)) = 2
sqrt (-4) = sqrt(abs(-4)) = 2
INF - 1000 = Some Large Value - 100
INF - 1000 = Some Large Value - 100
</source>


And there's many more combinations, but the point is that the results are not the same between PC and the PS2.
And there's many more combinations, but the point is that the results are not the same between PC and the PS2.
Line 68: Line 72:
Let me give you a quick example of something clamping can solve:
Let me give you a quick example of something clamping can solve:


<nowiki>
<source lang="cpp">
int main() {
int main() {
     float value = INF;
     float value = INF;
Line 75: Line 79:
         if (value <= 1)  { print("Hello World"); break; }
         if (value <= 1)  { print("Hello World"); break; }
     } while (true);
     } while (true);
}</nowiki>
}
</source>


If the above code was ran on the ps2, it will eventually print "Hello World", because INF is treated as a regular large number, and will continue to be divided by 2 until its less than 1.
If the above code was ran on the ps2, it will eventually print "Hello World", because INF is treated as a regular large number, and will continue to be divided by 2 until its less than 1.
Line 84: Line 89:
Clamping can solve this problem like this:
Clamping can solve this problem like this:


<nowiki>
<source lang="cpp">
int main() {
int main() {
     float value = INF;
     float value = INF;
Line 92: Line 97:
         if (value <= 1)  { print("Hello World"); break; }
         if (value <= 1)  { print("Hello World"); break; }
     } while (true);
     } while (true);
}</nowiki>
}
</source>


The clamping will convert the INF into a normal (ordered) number. Then that normal number can be divided by 2 repetitively until its less than 1. Then it will eventually satisfy (value less or equal 1), and print "Hello World".
The clamping will convert the INF into a normal (ordered) number. Then that normal number can be divided by 2 repetitively until its less than 1. Then it will eventually satisfy (value less or equal 1), and print "Hello World".
Line 103: Line 109:
Also clamping is SLOW if done a lot, so different clamp modes are faster than others ('None' is the fastest of course Razz)
Also clamping is SLOW if done a lot, so different clamp modes are faster than others ('None' is the fastest of course Razz)


I also should mention that in earlier examples i said:


I also should mention that in earlier examples i said:
<source lang="cpp">
sqrt(-4) = NaN; // on your PC
sqrt(-4) = NaN; // on your PC
sqrt(-4) = 2; // on the ps2
sqrt(-4) = 2; // on the ps2
</source>


In this case, we simulate the ps2's sqrt instruction by doing this
In this case, we simulate the ps2's sqrt instruction by doing this


<nowiki>
<source lang="cpp">
float ps2_sqrt(float value) {
float ps2_sqrt(float value) {
     value = clamp(value); // Clamp Value if NaN or Inf to an ordered/normal number
     value = clamp(value); // Clamp Value if NaN or Inf to an ordered/normal number
Line 116: Line 124:
     value = sqrt(value); // Get sqrt of now-positive value
     value = sqrt(value); // Get sqrt of now-positive value
     return value;
     return value;
}</nowiki>
}
</source>


so:
so:
<source lang="cpp">
ps2_sqrt(-4) = 2;
ps2_sqrt(-4) = 2;
 
</source>


Now this post is getting really large, and I tried to simplify things a lot (which may have made things more confusing).
Now this post is getting really large, and I tried to simplify things a lot (which may have made things more confusing).
Anyways I hope some of this info was useful/interesting
Anyways I hope some of this info was useful/interesting


{{PCSX2 Developers Blog Navbox}}
{{PCSX2 Developers Blog Navbox}}
ninja
782

edits