]> www.ginac.de Git - cln.git/blob - src/float/lfloat/elem/cl_LF_ftrunc.cc
4f45f01f31e6ba5e53468d56464f1a2c128ac262
[cln.git] / src / float / lfloat / elem / cl_LF_ftrunc.cc
1 // ftruncate().
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_LF_impl.h"
14 #include "cl_DS.h"
15
16 const cl_LF ftruncate (const cl_LF& x)
17 {
18 // Methode:
19 // x = 0.0 oder e<=0 -> Ergebnis 0.0
20 // 1<=e<=16n -> letzte (16n-e) Bits der Mantisse auf 0 setzen,
21 //              Exponent und Vorzeichen beibehalten
22 // e>=16n -> Ergebnis x
23 #if 0
24       var cl_signean sign;
25       var sintL exp;
26       var const uintD* mantMSDptr;
27       var uintC mantlen;
28       LF_decode(x, { return x; }, sign=,exp=,mantMSDptr=,mantlen=,);
29       if (exp<=0) { return encode_LF0(mantlen); } // e<=0 -> Ergebnis 0.0
30       if ((uintL)exp >= intDsize*(uintL)mantlen) // e>=16n -> x als Ergebnis
31         { return x; }
32         else
33         // 0 < e < 16n
34         // neue NUDS erzeugen mit e Bits aus mant und 16n-e Nullbits:
35         { CL_ALLOCA_STACK;
36           var uintD* MSDptr;
37           num_stack_alloc(mantlen, MSDptr=,);
38           { var uintC count = floor((uintL)exp,intDsize); // zu kopierende Digits, < mantlen
39             var uintC bitcount = ((uintL)exp) % intDsize; // zu kopierende Bits danach, >=0, <intDsize
40             var uintD* ptr =
41               copy_loop_msp(mantMSDptr,MSDptr,count); // count ganze Digits kopieren
42             msprefnext(ptr) = mspref(mantMSDptr,count) & minus_bitm(intDsize-bitcount); // dann bitcount Bits kopieren
43             clear_loop_msp(ptr,mantlen-count-1); // Rest mit Nullen füllen
44           }
45           return encode_LF(sign,exp,MSDptr,mantlen);
46         }
47 #else
48       var uintC len = TheLfloat(x)->len;
49       var uintL uexp = TheLfloat(x)->expo;
50       if (uexp <= LF_exp_mid)
51         { if (uexp == 0) { return x; } // x=0.0 -> Ergebnis 0.0
52           return encode_LF0(len); // e<=0 -> Ergebnis 0.0
53         }
54       var uintL exp = uexp - LF_exp_mid;
55       if (exp >= intDsize*(uintL)len) // e>=16n -> x als Ergebnis
56         { return x; }
57       // 0 < e < 16n
58       var Lfloat y = allocate_lfloat(len,uexp,TheLfloat(x)->sign); // neues Long-Float
59       // y_mant := NUDS mit e Bits aus x_mant und 16n-e Nullbits:
60       {var uintC count = floor(exp,intDsize); // zu kopierende Digits, < mantlen
61        var uintC bitcount = exp % intDsize; // zu kopierende Bits danach, >=0, <intDsize
62        var const uintD* x_mantMSDptr = LF_MSDptr(x);
63        var uintD* ptr =
64          copy_loop_msp(x_mantMSDptr,arrayMSDptr(TheLfloat(y)->data,len),count); // count ganze Digits kopieren
65        msprefnext(ptr) = mspref(x_mantMSDptr,count) & minus_bitm(intDsize-bitcount); // dann bitcount Bits kopieren
66        clear_loop_msp(ptr,len-count-1); // Rest mit Nullen füllen
67       }
68       return y;
69 #endif
70 }