diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2008-01-27 11:37:44 +0100 |
---|---|---|
committer | Tobias Klauser <tklauser@xenon.tklauser.home> | 2008-01-27 11:37:44 +0100 |
commit | 7e0f021a9aec35fd8e6725e87e3313b101d26f5e (patch) | |
tree | b1cacc4b24393f517aeb4610e9e1021f954307a8 /reference/C/CONTRIB/SNIP/ldfloor.c |
Initial import (2.0.2-6)2.0.2-6
Diffstat (limited to 'reference/C/CONTRIB/SNIP/ldfloor.c')
-rwxr-xr-x | reference/C/CONTRIB/SNIP/ldfloor.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/ldfloor.c b/reference/C/CONTRIB/SNIP/ldfloor.c new file mode 100755 index 0000000..acea285 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ldfloor.c @@ -0,0 +1,41 @@ +/* ldfloor() -- long double floor
+** public domain by Raymond Gardner Englewood, CO
+** tested with TC++
+** assumptions: 80-bit IEEE format numbers, stored LSB first
+** (Intel style), longs & ints are accessed from arbitrary boundaries
+*/
+
+long double ldfloor(long double a)
+{
+ long double a0;
+ int e, n;
+
+ a0 = a;
+ e = ((int *)&a)[4] & 0x7FFF; /* extract exponent */
+ if ( e == 0 ) /* 0 is special case */
+ return (long double) 0.0;
+ e -= 16383; /* unbias exponent */
+ if (e < 0) /* if < 0, num is < 1,... */
+ {
+ a = 0.0; /* so floor is zero */
+ }
+ else if ((n = 63 - e) > 0) /* clear n least sig. bits */
+ {
+ if (n < 32) /* clear n lowest bits */
+ {
+ ((unsigned long *)&a)[0] &= ~((1L << n) - 1);
+ }
+ else /* n >= 32 */
+ {
+ ((unsigned long *)&a)[0] = 0; /* clear lower 32 bits */
+ n -= 32; /* how many left to clear ? */
+ if (n) /* if any, clear n next lowest bits */
+ {
+ ((unsigned long *)&a)[1] &= ~((1L << n) - 1);
+ }
+ }
+ }
+ if (a0 < 0 && a0 != a) /* if neg. and it had fractional bits */
+ a -= 1.0; /* adjust the floor */
+ return a; /* return it */
+}
|