]> www.ginac.de Git - cln.git/blob - src/float/lfloat/elem/cl_LF_futrunc.cc
* All Files have been modified for inclusion of namespace cln;
[cln.git] / src / float / lfloat / elem / cl_LF_futrunc.cc
1 // futruncate().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_LF.h"
8
9
10 // Implementation.
11
12 #include "cl_LF_impl.h"
13 #include "cl_DS.h"
14
15 namespace cln {
16
17 const cl_LF futruncate (const cl_LF& x)
18 {
19 // Methode:
20 // x = 0.0 -> Ergebnis 0.0
21 // e<=0 -> Ergebnis 1.0 oder -1.0, je nach Vorzeichen von x.
22 // 1<=e<16n -> Greife die letzten (16n-e) Bits von x heraus.
23 //             Sind sie alle =0 -> Ergebnis x.
24 //             Sonst setze sie alle auf 0 und erhöhe dann die vorderen e Bits
25 //             um 1.
26 //             Kein Überlauf -> fertig.
27 //             Sonst (Ergebnis eine Zweierpotenz): Mantisse := .1000...000,
28 //               e:=e+1. (Test auf Überlauf wegen e<=16n überflüssig)
29 // e>=16n -> Ergebnis x.
30 #if 0
31       var cl_signean sign;
32       var sintL exp;
33       var const uintD* mantMSDptr;
34       var uintC mantlen;
35       LF_decode(x, { return x; }, sign=,exp=,mantMSDptr=,mantlen=,);
36       if (exp<=0) { return encode_LF1s(sign,mantlen); } // e<=0 -> Ergebnis +-1.0
37       if ((uintL)exp >= intDsize*(uintL)mantlen) // e>=16n -> x als Ergebnis
38         { return x; }
39         else
40         // 0 < e < 16n
41         { // Testen, ob alle hinteren 16n-e Bits =0 sind:
42           var uintC count = floor((uintL)exp,intDsize); // zu kopierende Digits, < mantlen
43           var uintC bitcount = ((uintL)exp) % intDsize; // zu kopierende Bits danach, >=0, <intDsize
44           var uintD mask = minus_bitm(intDsize-bitcount); // Maske mit bitcount Bits
45           var uintD* mantptr = mantMSDptr mspop count;
46           if (   ((mspref(mantptr,0) & ~mask) ==0)
47               && !test_loop_msp(mantptr mspop 1,mantlen-count-1)
48              )
49             { return x; }
50           // neue NUDS erzeugen mit e Bits aus mant mit Increment
51           // und 16n-e Nullbits:
52           CL_ALLOCA_STACK;
53           var uintD* MSDptr;
54           num_stack_alloc(mantlen, MSDptr=,);
55           { var uintD* ptr =
56               copy_loop_msp(mantMSDptr,MSDptr,count); // count ganze Digits kopieren
57             if ((mspref(ptr,0) = ((mspref(mantptr,0) & mask) - mask)) == 0) // dann bitcount Bits kopieren und incrementieren
58               { if (!( inc_loop_lsp(ptr,count) ==0)) // evtl. weiterincrementieren
59                   { mspref(MSDptr,0) = bit(intDsize-1); exp = exp+1; } // evtl. Exponenten erhöhen
60               }
61             clear_loop_msp(ptr mspop 1,mantlen-count-1); // Rest mit Nullen füllen
62           }
63           return encode_LF(sign,exp,MSDptr,mantlen);
64         }
65 #else
66       var uintC len = TheLfloat(x)->len;
67       var uintL uexp = TheLfloat(x)->expo;
68       if (uexp <= LF_exp_mid)
69         { if (uexp == 0) { return x; } // x=0.0 -> Ergebnis 0.0
70           return encode_LF1s(TheLfloat(x)->sign,len); // e<=0 -> Ergebnis +-1.0
71         }
72       var uintL exp = uexp - LF_exp_mid;
73       if (exp >= intDsize*(uintL)len) // e>=16n -> x als Ergebnis
74         { return x; }
75       // 0 < e < 16n
76       // Testen, ob alle hinteren 16n-e Bits =0 sind:
77       var uintC count = floor(exp,intDsize); // zu kopierende Digits, < mantlen
78       var uintC bitcount = exp % intDsize; // zu kopierende Bits danach, >=0, <intDsize
79       var uintD mask = minus_bitm(intDsize-bitcount); // Maske mit bitcount Bits
80       {var const uintD* mantptr = LF_MSDptr(x) mspop count;
81        if (   ((mspref(mantptr,0) & ~mask) ==0)
82            && !test_loop_msp(mantptr mspop 1,len-count-1)
83           )
84          { return x; }
85       }
86       // Nein -> neues Long-Float produzieren:
87       var Lfloat y = allocate_lfloat(len,uexp,TheLfloat(x)->sign); // neues Long-Float
88       // y_mant := NUDS mit e Bits aus x_mant mit Increment und 16n-e Nullbits:
89       {var const uintD* x_mantMSDptr = LF_MSDptr(x);
90        var uintD* y_mantMSDptr = arrayMSDptr(TheLfloat(y)->data,len);
91        var uintD* ptr =
92          copy_loop_msp(x_mantMSDptr,y_mantMSDptr,count); // count ganze Digits kopieren
93        if ((mspref(ptr,0) = ((mspref(x_mantMSDptr,count) & mask) - mask)) == 0) // dann bitcount Bits kopieren und incrementieren
94          { if (!( inc_loop_lsp(ptr,count) ==0)) // evtl. weiterincrementieren
95              { mspref(y_mantMSDptr,0) = bit(intDsize-1); (TheLfloat(y)->expo)++; } // evtl. Exponenten erhöhen
96          }
97        clear_loop_msp(ptr mspop 1,len-count-1); // Rest mit Nullen füllen
98       }
99       return y;
100 #endif
101 }
102
103 }  // namespace cln