24 #include "numtypelist.h"
28 #include "TypeManip.h"
29 #include "TypeTraits.h"
41 static const base_t DefaultBase = 1000000000;
42 static const base_t DefaultDecimalBase = 1000000000;
46 static const base_t DefaultBase = 10000;
47 static const base_t DefaultDecimalBase = 10000;
56 template<
bool S,
class NList,
57 base_t B = DefaultBase>
59 static const bool isPositive = S;
60 static const base_t Base = B;
64 template<
typename T1,
typename T2>
70 template<
class F1,
class F2>
73 template<
class F1,
class F2>
76 template<
class F1,
class F2>
82 template<
class F1,
class F2>
85 template<
class F1,
class F2>
94 template<
class N, base_t Base>
98 template<
class T,
int Accuracy, base_t Base = DefaultBase>
101 template<
int_t N,
int Accuracy, base_t Base>
102 struct Reduce<
SInt<N>,Accuracy,Base> {
110 template<
class BInt,
class RetType,
unsigned long AccumBase = 1>
111 struct Evaluate2IntLoop;
113 template<
bool S,
class H,
class T, base_t Base,
class RetType,
unsigned long AccumBase>
114 struct Evaluate2IntLoop<
SBigInt<S,Loki::Typelist<H,T>,Base>,RetType,AccumBase>
116 static const RetType Next = Evaluate2IntLoop<SBigInt<S,T,Base>,RetType,AccumBase*Base>::value;
117 static const RetType value = H::value*AccumBase + Next;
120 template<
bool S, base_t Base,
class RetType,
unsigned long AccumBase>
121 struct Evaluate2IntLoop<
SBigInt<S,Loki::NullType,Base>,RetType,AccumBase>
123 static const RetType value = 0;
126 template<
class BInt,
class RetType>
129 template<
bool S,
class NList, base_t Base,
class RetType>
130 struct Evaluate2Int<
SBigInt<S,NList,Base>,RetType>
132 static const RetType v = Evaluate2IntLoop<SBigInt<S,NList,Base>,RetType>::value;
133 static const RetType value = S ? v : -v;
136 template<
int_t N,
class RetType>
137 struct Evaluate2Int<
SInt<N>, RetType>
139 static const RetType value = N;
143 template<
class BInt,
class RetType>
144 struct EvaluateToFloatLoop;
146 template<
bool S,
class H,
class T, base_t Base,
class RetType>
147 struct EvaluateToFloatLoop<
SBigInt<S,Loki::Typelist<H,T>,Base>,RetType>
149 static RetType value()
151 return static_cast<RetType
>(H::value) + Base * EvaluateToFloatLoop<
SBigInt<S,T,Base>,RetType>::value();
155 template<
bool S,
class H, base_t Base,
class RetType>
156 struct EvaluateToFloatLoop<
SBigInt<S,Loki::Typelist<H,Loki::NullType>,Base>,RetType>
158 static RetType value() {
return static_cast<RetType
>(H::value); }
161 template<
bool S, base_t Base,
class RetType>
162 struct EvaluateToFloatLoop<
SBigInt<S,Loki::NullType,Base>,RetType>
164 static RetType value() {
return static_cast<RetType
>(0); }
168 template<
class BInt,
class RetType>
169 struct EvaluateToFloat;
171 template<
bool S,
class NList, base_t Base,
class RetType>
172 struct EvaluateToFloat<
SBigInt<S,NList,Base>,RetType>
174 static RetType value()
176 RetType v = EvaluateToFloatLoop<SBigInt<S,NList,Base>,RetType>::value();
181 template<
int_t N,
class RetType>
182 struct EvaluateToFloat<
SInt<N>,RetType>
184 static RetType value() {
return static_cast<RetType
>(N); }
191 template<
bool S1,
class N1,
bool S2,
class N2, base_t B>
194 static const int c = Compare<N1,N2>::value;
195 static const int value = (S1 && S2) ? c : (!S1 && !S2) ? -c
196 : (S1 && !S2) ? 1 : -1;
199 template<
int_t N1,
int_t N2>
202 static const int value = (N1 > N2) ? 1 : (N1 < N2) ? -1 : 0;
205 template<
bool S1,
class N1, base_t Base,
int_t N2>
208 typedef typename CreateBigInt<SInt<N2>,Base>::Result BI;
209 static const int value = Compare<SBigInt<S1,N1,Base>,BI>::value;
212 template<
bool S1,
class N1, base_t B1,
int_t N2>
215 static const int value = -Compare<SBigInt<S1,N1,B1>,
SInt<N2> >::value;
218 template<
class N1,
class N2>
219 struct CompareAbs :
public Compare<typename Abs<N1>::Result, typename Abs<N2>::Result> {};
225 template<
bool S,
class NList, base_t B>
226 struct Length<
SBigInt<S,NList,B> > {
227 static const int value = Loki::TL::Length<NList>::value;
231 struct Length<
SInt<N> > {
232 static const int value = 1;
249 template<
class NList, base_t Base,
int_t Rest=0>
252 template<
class H,
class T, base_t Base,
int_t Rest>
253 struct Align<Loki::Typelist<H,T>,Base,Rest> {
254 static const int_t A = H::value+Rest;
255 typedef Loki::Typelist<SInt<A%Base>,
256 typename Align<T,Base,A/Base>::Result> Result;
259 template<base_t Base,
int_t Rest>
260 struct Align<Loki::NullType,Base,Rest> {
261 typedef Loki::Typelist<SInt<Rest%Base>,
262 typename Align<Loki::NullType,Base,Rest/Base>::Result> Result;
265 template<base_t Base>
266 struct Align<Loki::Typelist<SInt<0>,Loki::NullType>,Base,0> {
267 typedef Loki::NullType Result;
270 template<base_t Base>
271 struct Align<Loki::NullType,Base,0> {
272 typedef Loki::NullType Result;
277 template<
class N, base_t Base>
280 template<
bool S,
class N, base_t Base>
281 struct CreateBigInt<
SBigInt<S,N,Base>,Base> {
285 template<
int_t N, base_t Base>
286 struct CreateBigInt<
SInt<N>,Base> {
287 static const bool S = (N>=0);
288 typedef typename Abs<SInt<N> >::Result AN;
289 typedef typename Align<
290 Loki::Typelist<AN,Loki::NullType>,Base>::Result NList;
294 template<base_t Base>
295 struct CreateBigInt<
SInt<0>,Base> {
301 template<int_t N, base_t Base = DefaultBase,
302 bool isSmallEnough=((N>=0 && N<Base) || (N<0 && -N<Base))>
303 struct __SwitchToBigInt;
305 template<
int_t N, base_t Base>
306 struct __SwitchToBigInt<N,Base,true> {
310 template<
int_t N, base_t Base>
311 struct __SwitchToBigInt<N,Base,false> {
312 typedef typename CreateBigInt<SInt<N>,Base>::Result Result;
318 int_t L = NL::Length<N>::value>
319 struct __SwitchToInt {
324 struct __SwitchToInt<N,1> {
329 struct __SwitchToInt<N,0> {
339 template<
int_t N1,
int_t N2>
341 typedef typename __SwitchToBigInt<N1+N2>::Result Result;
345 struct Add<
SInt<N>, Loki::NullType> {
350 struct Add<Loki::NullType,
SInt<N> > {
359 template<
int_t N1,
int_t N2>
360 struct Sub<
SInt<N1>,
SInt<N2> > :
public Add<SInt<N1>, SInt<-N2> > {};
377 template<
int_t N1,
int_t N2>
379 typedef typename __SwitchToBigInt<N1*N2>::Result Result;
387 template<
int_t N1,
int_t N2>
398 template<
int_t N1,
int_t N2>
409 static const int_t AN = (N>0) ? N : -N ;
419 template<
bool S,
class NList, base_t Base>
431 template<
bool S,
class NList, base_t Base>
438 struct Sign<
SInt<N> > {
439 static const char value = (N>0) ? 1 : ((N<0) ? -1 : 0);
442 template<
bool S,
class NList, base_t Base>
443 struct Sign<
SBigInt<S,NList,Base> > {
444 static const char value = S ? 1 : -1;
447 template<
bool S, base_t Base>
448 struct Sign<
SBigInt<S,Loki::NullType,Base> > {
449 static const char value = 0;
457 template<
bool S,
typename NList, base_t Base>
458 struct Simplify<
SBigInt<S,NList,Base> > {
459 typedef typename NL::CutTrailingZeros<NList>::Result NewList;
460 typedef typename __SwitchToInt<SBigInt<S,NewList,Base> >::Result Result;
464 struct Simplify<
SInt<N> > {
470 template<
class B1,
class B2,
int Comparison>
473 template<
class NList1,
class NList2, base_t Base>
474 struct __Add<
SBigInt<true,NList1,Base>,
SBigInt<true,NList2,Base>,1> {
482 template<
class NList1,
class NList2, base_t Base>
483 struct __Add<
SBigInt<true,NList1,Base>,
SBigInt<false,NList2,Base>,1> {
485 static const int_t L = Loki::TL::Length<NList1>::value;
490 typedef typename Loki::TL::EraseAt<ADif,L>::Result ADif1;
496 template<
class NList1,
class NList2, base_t Base>
497 struct __Add<
SBigInt<false,NList1,Base>,
SBigInt<true,NList2,Base>,1> {
498 typedef typename Negate<
499 typename __Add<SBigInt<true,NList1,Base>,
503 template<
class NList1,
class NList2, base_t Base>
504 struct __Add<
SBigInt<false,NList1,Base>,
SBigInt<false,NList2,Base>,1> {
505 typedef typename Negate<
506 typename __Add<SBigInt<true,NList1,Base>,
510 template<
bool S1,
bool S2,
class NList1,
class NList2, base_t Base>
511 struct __Add<
SBigInt<S1,NList1,Base>,
SBigInt<S2,NList2,Base>,-1> {
515 template<
class NList1,
class NList2, base_t Base>
516 struct __Add<
SBigInt<true,NList1,Base>,
SBigInt<true,NList2,Base>,0>
517 :
public __Add<SBigInt<true,NList1,Base>,SBigInt<true,NList2,Base>,1> {};
519 template<
class NList1,
class NList2, base_t Base>
520 struct __Add<
SBigInt<true,NList1,Base>,
SBigInt<false,NList2,Base>,0> {
524 template<
class NList1,
class NList2, base_t Base>
525 struct __Add<
SBigInt<false,NList1,Base>,
SBigInt<true,NList2,Base>,0> {
529 template<
class NList1,
class NList2, base_t Base>
530 struct __Add<
SBigInt<false,NList1,Base>,
SBigInt<false,NList2,Base>,0>
531 :
public __Add<SBigInt<false,NList1,Base>,SBigInt<false,NList2,Base>,1> {};
535 template<
bool S1,
class NList1,
bool S2,
class NList2, base_t Base>
541 typedef typename __Add<BI1,BI2,C>::Result Result;
544 template<
bool S,
class NList, base_t Base,
int_t N>
548 typedef typename CreateBigInt<SInt<N>,Base>::Result BI2;
550 typedef typename __Add<BI1,BI2,C>::Result Result;
553 template<
bool S,
class NList, base_t Base,
int_t N>
554 class Add<
SInt<N>,
SBigInt<S,NList,Base> > :
public Add<SBigInt<S,NList,Base>,SInt<N> > {};
556 template<
bool S,
class NList, base_t Base>
562 template<
bool S, base_t Base,
int_t N>
563 class Add<
SBigInt<S,Loki::NullType,Base>,
SInt<N> > {
569 template<
bool S1,
class NList1,
bool S2,
class NList2, base_t Base>
575 typedef typename __Add<BI1,BI2,C>::Result Result;
578 template<
bool S,
class NList, base_t Base,
int_t N>
579 class Sub<
SBigInt<S,NList,Base>,
SInt<N> > :
public Add<SBigInt<S,NList,Base>,SInt<-N> > {};
581 template<
bool S,
class NList, base_t Base,
int_t N>
584 typedef typename Negate<
585 typename Sub<SBigInt<S,NList,Base>,
SInt<N> >::Result>::Result Result;
590 template<
class NList1,
class NList2, base_t Base,
int_t I=0>
593 template<
class Num,
class Tail,
class NList2, base_t Base,
int_t I>
594 struct __MultLoop<Loki::Typelist<Num,Tail>,NList2,Base,I> {
598 typedef typename Loki::TL::Append<Shift,Prod>::Result ShiftedProd;
601 typename __MultLoop<Tail,NList2,Base,I+1>::Result>::Result,Base>::Result Result;
604 template<
class NList2, base_t Base,
int_t I>
605 struct __MultLoop<Loki::NullType,NList2,Base,I> {
606 typedef Loki::NullType Result;
611 template<
bool S1,
class NList1,
bool S2,
class NList2, base_t Base>
613 typedef typename __MultLoop<NList1,NList2,Base>::Result NListProd;
619 template<
bool S,
class NList, base_t Base,
int_t N>
621 static const int_t A = (N<0) ? -N : N ;
622 static const bool S1 = (N>=0);
629 template<
bool S,
class NList, base_t Base>
635 template<
bool S,
class NList, base_t Base>
641 template<
bool S,
class NList, base_t Base>
647 template<
bool S,
class NList, base_t Base>
653 template<
bool S,
class NList, base_t Base>
659 template<
bool S,
class NList, base_t Base,
int_t N>
662 typedef typename Mult<SBigInt<S,NList,Base>,
SInt<N> >::Result Result;
671 struct SelectUList<
SInt<0> > {
672 typedef Loki::NullType Result;
675 template<
bool S,
class NList, base_t Base>
676 struct SelectUList<
SBigInt<S,NList,Base> > {
677 typedef NList Result;
681 template<
class NList1,
class NList2, base_t Base, int_t I,
682 unsigned int NList1Len, int_t V1, int_t V2>
685 template<
class H,
class T,
class NList2, base_t Base, int_t I,
686 unsigned int NList1Len, int_t V1, int_t V2>
687 class __Div<Loki::Typelist<H,T>,NList2,Base,I,NList1Len,V1,V2> {
688 typedef __Div<T,NList2,Base,I-1,NList1Len-1,V1,V2> Next;
689 typedef Loki::Typelist<H,typename Next::UList> NList1;
691 static const int_t U0 = Loki::TL::TypeAtNonStrict<UT,2,SInt<0> >::Result::value;
692 static const int_t U1 = Loki::TL::TypeAtNonStrict<UT,1,SInt<0> >::Result::value;
693 static const int_t U2 = Loki::TL::TypeAtNonStrict<UT,0,SInt<0> >::Result::value;
697 static const int_t U = U0*Base+U1;
698 static const uint_t Q = U/V1;
699 static const uint_t R = U%V1;
701 static const uint_t Q1 = ((Q==Base) || (Q*V2>R*Base+U2)) ? Q-1 : Q;
702 static const uint_t R1 = (Q1<Q) ? R+V1 : R;
704 static const int_t Q2 = ((R1<Base) && ((Q1==Base) || (Q1*V2>R1*Base+U2))) ? Q1-1 : Q1;
709 typedef typename Sub<BI1,typename Mult<BI2,SInt<Q2> >::Result>::Result Dif;
713 typedef Loki::Typelist<SInt<Q2>,
typename Next::DivList> DivList;
714 typedef typename SelectUList<Dif>::Result UList;
717 template<
class H,
class T,
class NList2, base_t Base,
718 unsigned int NList1Len, int_t V1, int_t V2>
719 class __Div<Loki::Typelist<H,T>,NList2,Base,0,NList1Len,V1,V2> {
721 typedef Loki::NullType DivList;
722 typedef Loki::Typelist<H,T> UList;
727 template<
class B1,
class B2>
731 template<
class B1,
class B2,
int_t L1,
int_t L2,
char C>
734 template<
class B1,
class B2,
int_t L1,
int_t L2>
735 struct DivSelect<B1,B2,L1,L2,1> {
736 typedef typename Simplify<B1>::Result BS1;
737 typedef typename Simplify<B2>::Result BS2;
738 typedef BigDiv<BS1,BS2> T;
740 typedef typename T::DivResult DivResult;
741 typedef typename T::ModResult ModResult;
744 template<
class B1,
class B2,
int_t L1,
int_t L2>
745 struct DivSelect<B1,B2,L1,L2,-1> {
747 typedef B1 ModResult;
750 template<
class B1,
class B2,
int_t L1,
int_t L2>
751 struct DivSelect<B1,B2,L1,L2,0> {
756 template<
class B1,
class B2,
int_t L>
757 struct DivSelect<B1,B2,2,L,1> {
760 typedef Div<I1,I2> T;
761 typedef typename T::DivResult DivResult;
762 typedef typename T::ModResult ModResult;
765 template<
class B1,
class B2>
766 struct DivSelect<B1,B2,2,1,1> {
769 typedef Div<I1,I2> T;
770 typedef typename T::DivResult DivResult;
771 typedef typename T::ModResult ModResult;
774 template<
class B1,
class B2,
int_t L>
775 struct DivSelect<B1,B2,L,1,1> {
777 typedef Div<B1,I2> T;
778 typedef typename T::DivResult DivResult;
779 typedef typename T::ModResult ModResult;
783 template<
bool S1,
class NList1,
bool S2,
class NList2, base_t Base>
788 static const unsigned L1 = Loki::TL::Length<NList1>::value;
789 static const unsigned L2 = Loki::TL::Length<NList2>::value;
793 static const int_t D = Base/(Loki::TL::TypeAt<NList2,L2-1>::Result::value+1);
794 typedef typename Mult<BI1,SInt<D> >::Result U;
795 static const unsigned int ULen = Loki::TL::Length<typename U::Num>::value;
796 typedef typename Loki::Select<(ULen==L1),
797 typename Loki::TL::Append<
typename U::Num,
SInt<0> >::Result,
798 typename U::Num>::Result UList;
799 typedef typename Mult<BI2,SInt<D> >::Result V;
802 static const unsigned int UListLen = (ULen==L1) ? ULen+1 : ULen;
803 typedef typename V::Num VList;
804 static const unsigned int VLen = Loki::TL::Length<VList>::value;
805 static const int_t V1 = Loki::TL::TypeAt<VList,VLen-1>::Result::value;
806 static const int_t V2 = Loki::TL::TypeAt<VList,VLen-2>::Result::value;
807 typedef __Div<UList,VList,Base,L1-L2+1,UListLen,V1,V2> Loop;
813 typedef typename Div<ModT,SInt<D> >::DivResult ModResult;
819 template<
class List,
class N, base_t Base>
822 template<
class H,
class T,
int_t N, base_t Base>
823 struct __DivN<Loki::Typelist<H,T>,
SInt<N>,Base> {
824 typedef __DivN<T,SInt<N>,Base> Next;
825 static const int_t AN = (N>0) ? N : -N;
826 static const int_t B = Next::Q*Base + H::value;
827 static const int_t R = B/AN;
828 static const int_t Q = B%AN;
829 typedef Loki::Typelist<SInt<R>,
typename Next::Result> Result;
832 template<
int_t N, base_t Base>
833 struct __DivN<Loki::NullType,
SInt<N>,Base> {
834 static const int_t Q = 0;
835 typedef Loki::NullType Result;
840 template<
bool S1,
class NList1,
bool S2,
class NList2, base_t Base>
843 static const int_t L1 = Loki::TL::Length<NList1>::value;
844 static const int_t L2 = Loki::TL::Length<NList2>::value;
849 typedef typename Simplify<typename T::DivResult>::Result DivResult;
850 typedef typename Simplify<typename T::ModResult>::Result ModResult;
856 template<
bool S1,
bool S2,
class NList2, base_t Base>
857 class Div<
SBigInt<S1,Loki::NullType,Base>,
SBigInt<S2,NList2,Base> > {
863 template<
bool S1,
class NList1,
bool S2, base_t Base>
864 class Div<
SBigInt<S1,NList1,Base>,
SBigInt<S2,Loki::NullType,Base> > {};
868 template<
bool S,
class H,
class T, base_t Base,
int_t N>
869 class Div<
SBigInt<S,Loki::Typelist<H,T>,Base>,
SInt<N> > {
870 typedef __DivN<Loki::Typelist<H,T>,
typename Abs<SInt<N> >::Result,Base> DivLoop;
873 typedef typename Simplify<BI>::Result DivResult;
877 template<
bool S,
class H,
class T, base_t Base>
878 class Div<
SBigInt<S,Loki::Typelist<H,T>,Base>,
SInt<1> > {
884 template<
bool S,
class H,
class T, base_t Base>
885 class Div<
SBigInt<S,Loki::Typelist<H,T>,Base>,
SInt<0> > {};
887 template<
bool S,
class H,
class T, base_t Base>
888 class Div<
SInt<0>,
SBigInt<S,Loki::Typelist<H,T>,Base> > {
894 template<
bool S, base_t Base,
int_t N>
895 class Div<
SBigInt<S,Loki::NullType,Base>,
SInt<N> > {
901 template<
bool S, base_t Base,
int_t N>
902 class Div<
SInt<N>,
SBigInt<S,Loki::NullType,Base> > {};
905 template<
bool S,
class NList, base_t Base,
int_t N>
908 typedef typename Div<SBigInt<S,NList,Base>,
SInt<N> >::Result Result;
931 template<
unsigned N,
unsigned Base>
933 static const unsigned value = NDigits<N/Base, Base>::value + 1;
936 template<
unsigned Base>
937 struct NDigits<0, Base> {
938 static const unsigned value = 0;
943 template<
class B, base_t NewBase>
946 template<
bool S,
class H,
class T, base_t Base, base_t NewBase>
947 class Translate<
SBigInt<S,Loki::Typelist<H,T>,Base>,NewBase> {
949 typedef typename Translate<BI,NewBase>::Result Next;
951 typedef typename Add<typename Mult<Next,SInt<Base> >::Result,H>::Result Result;
954 template<
bool S, base_t Base, base_t NewBase>
955 class Translate<
SBigInt<S,Loki::NullType,Base>,NewBase> {
962 template<
class NList, base_t Base>
963 struct DoubleBaseLoop;
965 template<
class H1,
class H2,
class T, base_t Base>
966 struct DoubleBaseLoop<Loki::Typelist<H1,Loki::Typelist<H2,T> >,Base> {
967 static const int_t H = H2::value*Base + H1::value;
968 typedef Loki::Typelist<SInt<H>,
typename DoubleBaseLoop<T,Base>::Result> Result;
971 template<
class H1, base_t Base>
972 struct DoubleBaseLoop<Loki::Typelist<H1,Loki::NullType>,Base> {
973 typedef Loki::Typelist<H1,Loki::NullType> Result;
976 template<base_t Base>
977 struct DoubleBaseLoop<Loki::NullType,Base> {
978 typedef Loki::NullType Result;
985 template<
bool S,
class N, base_t Base>
986 struct DoubleBase<
SBigInt<S,N,Base> > {
987 typedef typename DoubleBaseLoop<N,Base>::Result List;
992 struct DoubleBase<
SInt<N> > {
998 template<
class H, base_t Base,
999 bool C = (Abs<H>::Result::value < Base)>
1002 template<
class H, base_t Base>
1003 struct CheckStep<H,Base,true> {
1007 template<
class H, base_t Base>
1008 struct CheckStep<H,Base,false> { };
1014 template<
bool S,
class H,
class T, base_t Base>
1015 struct Check<SBigInt<S,Loki::Typelist<H,T>,Base> >
1017 typedef Loki::Typelist<typename CheckStep<H,Base>::Result,
1018 typename Check<SBigInt<S,T,Base> >::Result> Result;
1021 template<
bool S, base_t Base>
1022 struct Check<
SBigInt<S,Loki::NullType,Base> >
1024 typedef Loki::NullType Result;
1028 struct Check<
SInt<N> > :
public CheckStep<SInt<N>,DefaultBase> {};