]> www.ginac.de Git - cln.git/blob - src/float/lfloat/misc/cl_LF_shorten.cc
Initial revision
[cln.git] / src / float / lfloat / misc / cl_LF_shorten.cc
1 // shorten().
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 #include "cl_F.h"
15
16 const cl_LF shorten (const cl_LF& x, uintC len)
17 {
18       // x = 0.0 braucht nicht abgefangen zu werden, da bei Mantisse 0 dann
19       // sowieso abgerundet wird, die Mantisse also 0 bleibt.
20       var Lfloat y = allocate_lfloat(len,TheLfloat(x)->expo,TheLfloat(x)->sign); // neues LF
21       { var uintC oldlen = TheLfloat(x)->len; // alte Länge, > len
22         // Mantisse von x nach y kopieren:
23         copy_loop_msp(arrayMSDptr(TheLfloat(x)->data,oldlen),arrayMSDptr(TheLfloat(y)->data,len),len);
24         // Entscheiden, ob auf- oder abrunden:
25         var uintD* ptr = arrayMSDptr(TheLfloat(x)->data,oldlen) mspop len;
26         if ( ((sintD)mspref(ptr,0) >= 0) // nächstes Bit eine 0 -> abrunden
27              || ( ((mspref(ptr,0) & ((uintD)bit(intDsize-1)-1)) ==0) // eine 1 und alles weitere Nullen?
28                   && !test_loop_msp(ptr mspop 1,oldlen-len-1)
29                   // round-to-even
30                   && ((lspref(ptr,0) & bit(0)) ==0)
31            )    )
32           // abrunden
33           {}
34           else
35           // aufrunden
36           { if ( inc_loop_lsp(arrayLSDptr(TheLfloat(y)->data,len),len) )
37               // Übertrag durch Aufrunden
38               { mspref(arrayMSDptr(TheLfloat(y)->data,len),0) = bit(intDsize-1); // Mantisse := 10...0
39                 // Exponent erhöhen:
40                 if (++(TheLfloat(y)->expo) == LF_exp_high+1) { cl_error_floating_point_overflow(); }
41           }   }
42       }
43       return y;
44 }