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