]> www.ginac.de Git - cln.git/blob - src/float/lfloat/elem/cl_LF_compare.cc
1a2e97c4f44fb829a3b2cc63b8b9507439f051e8
[cln.git] / src / float / lfloat / elem / cl_LF_compare.cc
1 // cl_compare().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_lfloat.h"
8
9
10 // Implementation.
11
12 #include "cl_LF.h"
13 #include "cl_DS.h"
14
15 #undef MAYBE_INLINE
16 #define MAYBE_INLINE inline
17 #include "cl_LF_minusp.cc"
18
19 cl_signean cl_compare (const cl_LF& x, const cl_LF& y)
20 {
21 // Methode:
22 // x und y haben verschiedenes Vorzeichen ->
23 //    x < 0 -> x < y
24 //    x >= 0 -> x > y
25 // x und y haben gleiches Vorzeichen ->
26 //    x >=0 -> vergleiche x und y (die rechten 24 Bits)
27 //    x <0 -> vergleiche y und x (die rechten 24 Bits)
28       if (!minusp(y))
29         // y>=0
30         { if (!minusp(x))
31             // y>=0, x>=0
32             { // Vergleiche Exponenten und Mantissen:
33               { var uintL x_uexp = TheLfloat(x)->expo;
34                 var uintL y_uexp = TheLfloat(y)->expo;
35                 if (x_uexp < y_uexp) return signean_minus; // x<y
36                 if (x_uexp > y_uexp) return signean_plus; // x>y
37               }
38               { var uintC x_len = TheLfloat(x)->len;
39                 var uintC y_len = TheLfloat(y)->len;
40                 var uintC len = (x_len<y_len ? x_len : y_len); // min(x_len,y_len)
41                 // len Digits vergleichen:
42                 var cl_signean erg =
43                   compare_loop_msp(arrayMSDptr(TheLfloat(x)->data,x_len),arrayMSDptr(TheLfloat(y)->data,y_len),len);
44                 if (!(erg==0)) { return erg; } // verschieden -> fertig
45                 // gemeinsames Teilstück war gleich
46                 if (x_len == y_len) { return signean_null; } // gleiche Länge -> fertig
47                 if (x_len > y_len)
48                   // x länger als y
49                   { if (DS_test_loop(arrayMSDptr(TheLfloat(x)->data,x_len) mspop y_len,x_len-y_len,arrayLSDptr(TheLfloat(x)->data,x_len)))
50                       { return signean_plus; } // x>y
51                       else
52                       { return signean_null; }
53                   }
54                   else
55                   // y länger als x
56                   { if (DS_test_loop(arrayMSDptr(TheLfloat(y)->data,y_len) mspop x_len,y_len-x_len,arrayLSDptr(TheLfloat(y)->data,y_len)))
57                       { return signean_minus; } // x<y
58                       else
59                       { return signean_null; }
60                   }
61             } }
62             else
63             // y>=0, x<0
64             { return signean_minus; } // x<y
65         }
66         else
67         { if (!minusp(x))
68             // y<0, x>=0
69             { return signean_plus; } // x>y
70             else
71             // y<0, x<0
72             { // Vergleiche Exponenten und Mantissen:
73               { var uintL x_uexp = TheLfloat(x)->expo;
74                 var uintL y_uexp = TheLfloat(y)->expo;
75                 if (x_uexp < y_uexp) return signean_plus; // |x|<|y| -> x>y
76                 if (x_uexp > y_uexp) return signean_minus; // |x|>|y| -> x<y
77               }
78               { var uintC x_len = TheLfloat(x)->len;
79                 var uintC y_len = TheLfloat(y)->len;
80                 var uintC len = (x_len<y_len ? x_len : y_len); // min(x_len,y_len)
81                 // len Digits vergleichen:
82                 var cl_signean erg =
83                   compare_loop_msp(arrayMSDptr(TheLfloat(y)->data,y_len),arrayMSDptr(TheLfloat(x)->data,x_len),len);
84                 if (!(erg==0)) { return erg; } // verschieden -> fertig
85                 // gemeinsames Teilstück war gleich
86                 if (x_len == y_len) { return signean_null; } // gleiche Länge -> fertig
87                 if (x_len > y_len)
88                   // x länger als y
89                   { if (DS_test_loop(arrayMSDptr(TheLfloat(x)->data,x_len) mspop y_len,x_len-y_len,arrayLSDptr(TheLfloat(x)->data,x_len)))
90                       { return signean_minus; } // |x|>|y| -> x<y
91                       else
92                       { return signean_null; }
93                   }
94                   else
95                   // y länger als x
96                   { if (DS_test_loop(arrayMSDptr(TheLfloat(y)->data,y_len) mspop x_len,y_len-x_len,arrayLSDptr(TheLfloat(y)->data,y_len)))
97                       { return signean_plus; } // |x|<|y| -> x>y
98                       else
99                       { return signean_null; }
100                   }
101             } }
102         }
103 }