revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / mathffp / spfloor.c
blob407374228a40d57e6f72c55916bf25e870c19b8b
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathffp_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LH1(float, SPFloor,
14 /* SYNOPSIS */
15 AROS_LHA(float, y, D0),
17 /* LOCATION */
18 struct LibHeader *, MathBase, 15, Mathffp)
20 /* FUNCTION
21 Calculate the largest integer ffp-number
22 less than or equal to fnum
24 INPUTS
26 RESULT
27 FFP number
29 Flags:
30 zero : result is zero
31 negative : result is negative
32 overflow : 0 (???)
34 EXAMPLE
35 floor(10.5) = 10
36 floor(0.5) = 0
37 floor(-0.5) = -1
38 floor(-10.5)= -11
40 BUGS
42 INTERNALS
43 ALGORITHM:
44 The integer part of a ffp number are the left "exponent"-bits
45 of the mantisse!
46 Therefore:
47 Test the exponent for <= 0. This has to be done separately!
48 If the sign is negative then return -1 otherwise return 0.
50 Generate a mask of exponent(y) (where y is the given ffp-number)
51 bits starting with bit 31.
52 If y < 0 then test whether it is already an integer. If not
53 then y = y - 1 and generate that mask again. Use the
54 mask on the mantisse.
56 *****************************************************************************/
58 AROS_LIBFUNC_INIT
60 LONG Mask = 0x80000000;
62 if (((char)y & FFPExponent_Mask) <= 0x40)
64 if ((char)y < 0)
66 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
67 return 0x800000C1; /* -1 */
69 else
71 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
72 return 0;
76 /* |fnum| >= 1 */
77 Mask >>= ( ((char) y & FFPExponent_Mask) - 0x41);
78 Mask |= FFPSign_Mask | FFPExponent_Mask;
80 /* fnum is negative */
81 if ((char) y < 0)
83 /* is there anything behind the dot? */
84 if (0 != (y & (~Mask)) )
86 Mask = 0x80000000;
87 y = SPAdd(y, 0x800000c1); /* y = y -1; */
88 Mask >>= ((char) y & FFPExponent_Mask) - 0x41;
89 Mask |= FFPSign_Mask | FFPExponent_Mask;
93 if((char) y < 0)
95 SetSR(Negative_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
98 return y & Mask;
100 AROS_LIBFUNC_EXIT