Generative Fast Fourier Transforms (GFFT)  0.3
sdecimal.h
1 /***************************************************************************
2  * Copyright (C) 2008-2014 by Vladimir Mirnyy *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 2 of the License, or *
7  * (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  ***************************************************************************/
14 
15 #ifndef __sdecimal_h
16 #define __sdecimal_h
17 
18 #include "sbigint.h"
19 
20 
21 template<class BigInt, int_t NDecPlaces, base_t DecBase>
22 struct SDecimal {
23  typedef BigInt Num;
24  static const int_t NDec = NDecPlaces;
25  static const base_t Base = DecBase;
26 };
27 
28 
29 template<class BI, unsigned int N, unsigned int I=N>
30 struct ShiftLeftRound;
31 
32 template<bool S, class H1, class H2, class T, base_t Base, unsigned int N, unsigned int I>
33 struct ShiftLeftRound<SBigInt<S,Loki::Typelist<H1,Loki::Typelist<H2,T> >,Base>,N,I>
34 {
35  static const base_t HalfBase = Base >> 1;
36  typedef typename Loki::Select<(H1::value >= HalfBase),
37  Loki::Typelist<SInt<H2::value+1>,T>,Loki::Typelist<H2,T> >::Result TList;
38  typedef typename ShiftLeftRound<SBigInt<S,TList,Base>,N,I-1>::Result Result;
39 };
40 
41 template<bool S, class H1, class H2, class T, base_t Base, unsigned int N>
42 struct ShiftLeftRound<SBigInt<S,Loki::Typelist<H1,Loki::Typelist<H2,T> >,Base>,N,0>
43 {
45 };
46 
47 template<bool S, class H1, base_t Base, unsigned int N, unsigned int I>
48 struct ShiftLeftRound<SBigInt<S,Loki::Typelist<H1,Loki::NullType>,Base>,N,I>
49 {
50  static const base_t HalfBase = Base >> 1;
51  typedef typename Loki::Select<(H1::value >= HalfBase),
52  Loki::Typelist<SInt<1>,Loki::NullType>,Loki::NullType>::Result TList;
53  typedef typename ShiftLeftRound<SBigInt<S,TList,Base>,N,I-1>::Result Result;
54 };
55 
56 template<bool S, class H1, base_t Base, unsigned int N>
57 struct ShiftLeftRound<SBigInt<S,Loki::Typelist<H1,Loki::NullType>,Base>,N,0>
58 {
60 };
61 
62 template<bool S, class TList, base_t Base, unsigned int N>
63 struct ShiftLeftRound<SBigInt<S,TList,Base>,N,0>
64 {
65  typedef SBigInt<S,TList,Base> Result;
66 };
67 
68 template<bool S, base_t Base, unsigned int N, unsigned int I>
69 struct ShiftLeftRound<SBigInt<S,Loki::NullType,Base>,N,I>
70 {
71  typedef SBigInt<S,Loki::NullType,Base> Result;
72 };
73 
74 template<bool S, base_t Base, unsigned int N>
75 struct ShiftLeftRound<SBigInt<S,Loki::NullType,Base>,N,0>
76 {
77  typedef SBigInt<S,Loki::NullType,Base> Result;
78 };
79 
80 
81 template<class BI, int_t ND, int Accuracy, base_t Base>
82 struct Reduce<SDecimal<BI,ND,Base>,Accuracy,Base> {
83 // typedef typename BI::Num NList;
84 // typedef typename Loki::Select<(ND>Accuracy),
85 // typename Loki::TL::ShiftLeft<NList,ND-Accuracy>::Result,NList>::Result NewList;
86 // typedef SDecimal<SBigInt<BI::isPositive,NewList,BI::Base>,Accuracy,Base> Result;
87 
88  typedef typename Loki::Select<(ND>Accuracy),
89  typename ShiftLeftRound<BI,ND-Accuracy>::Result,BI>::Result NewBI;
90  typedef SDecimal<NewBI,Accuracy,Base> Result;
91 };
92 
93 template<int_t N, int_t ND, int Accuracy, base_t Base>
94 struct Reduce<SDecimal<SInt<N>,ND,Base>,Accuracy,Base> {
95  typedef SDecimal<SInt<N>,Accuracy,Base> Result;
96 };
97 
98 template<class BI1, int_t ND1, class BI2, int_t ND2, base_t DecBase>
99 class Mult<SDecimal<BI1,ND1,DecBase>,SDecimal<BI2,ND2,DecBase> > {
100  static const int_t MaxND = (ND1 > ND2) ? ND1 : ND2;
101  typedef typename Mult<BI1,BI2>::Result Prod;
102  typedef SDecimal<Prod,ND1+ND2,DecBase> NewDec;
103 public:
104  typedef typename Reduce<NewDec,MaxND,DecBase>::Result Result;
105 };
106 
107 template<int_t N, class BI, int_t ND, base_t DecBase>
108 class Mult<SInt<N>,SDecimal<BI,ND,DecBase> > {
109  typedef typename Mult<SInt<N>,BI>::Result Prod;
110 public:
111  typedef SDecimal<Prod,ND,DecBase> Result;
112 };
113 
114 template<int_t N, class BI, int_t ND, base_t DecBase>
115 class Mult<SDecimal<BI,ND,DecBase>,SInt<N> >
116 : public Mult<SInt<N>,SDecimal<BI,ND,DecBase> > {};
117 
119 
120 template<class BI1, class BI2, int_t ND, base_t DecBase>
121 class Add<SDecimal<BI1,ND,DecBase>,SDecimal<BI2,ND,DecBase> > {
122  typedef typename Add<BI1,BI2>::Result Sum;
123 public:
124  typedef SDecimal<Sum,ND,DecBase> Result;
125 };
126 
127 template<class BI, int_t ND, base_t DecBase, int_t N>
128 class Add<SDecimal<BI,ND,DecBase>,SInt<N> > {
129  typedef typename CreateBigInt<SInt<N>,DecBase>::Result BI1;
130  typedef typename Loki::TL::ShiftRight<typename BI1::Num,ND,SInt<0> >::Result NList;
132  typedef typename Add<BI,NewBI>::Result Sum;
133 public:
134  typedef SDecimal<Sum,ND,DecBase> Result;
135 };
136 
138 
139 template<class BI1, class BI2, int_t ND, base_t DecBase>
140 class Sub<SDecimal<BI1,ND,DecBase>,SDecimal<BI2,ND,DecBase> > {
141  typedef typename Sub<BI1,BI2>::Result Dif;
142 public:
143  typedef SDecimal<Dif,ND,DecBase> Result;
144 };
145 
147 
148 template<class BI, int_t ND, base_t DecBase>
149 struct Negate<SDecimal<BI,ND,DecBase> > {
150  typedef typename Negate<BI>::Result NewBI;
151  typedef SDecimal<NewBI,ND,DecBase> Result;
152 };
153 
155 
156 template<class BI, int_t ND, base_t DecBase>
157 struct Check<SDecimal<BI,ND,DecBase> > : public Check<BI> {};
158 
159 #endif

Generated on Mon Feb 10 2014 for Generative Fast Fourier Transforms (GFFT) by DoxyGen 1.8.3.1