77#include " MultiwordInteger.hpp"
88#include " FixedPointHelpers.hpp"
99
10- template <unsigned size, typename storageType> template <unsigned otherSize> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(MultiwordInteger<otherSize, storageType> const &o) : s{0 } {
10+ template <unsigned size, typename storageType>
11+ template <unsigned otherSize>
12+ constexpr MultiwordInteger<size, storageType>::MultiwordInteger(MultiwordInteger<otherSize, storageType> const &o) : s{0 } {
1113 unsigned num = size > otherSize ? otherSize : size;
1214 for (unsigned i = 0 ; i < num; i++) {
1315 s[i] = o.s [i];
@@ -22,83 +24,19 @@ template<unsigned size, typename storageType> template<unsigned otherSize> const
2224 }
2325 }
2426}
25- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(storageType const &v) : s{v} {
27+
28+ template <unsigned size, typename storageType>
29+ constexpr MultiwordInteger<size, storageType>::MultiwordInteger(storageType const &v) : s{v} {
2630 if (static_cast <signedType>(v) < 0 ) {
2731 for (unsigned i = 1 ; i < size; i++) {
2832 s[i] = static_cast <signedType>(-1 );
2933 }
3034 }
3135}
32- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(int8_t v) : s{0 } {
33- *this = MultiwordInteger<size, std::make_unsigned<decltype (v)>::type>(v);
34- }
35- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(int16_t v) : s{0 } {
36- *this = MultiwordInteger<size, std::make_unsigned<decltype (v)>::type>(v);
37- }
38- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(int32_t v) : s{0 } {
39- *this = MultiwordInteger<size, std::make_unsigned<decltype (v)>::type>(v);
40- }
41- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(int64_t v) : s{0 } {
42- uint64_t uv = v;
43- unsigned i = 0 ;
44- for (; i < size && uv; i++) {
45- s[i] = uv;
46- uv >>= storageSize;
47- }
48- for (; i < size; i++) {
49- s[i] = 0 ;
50- }
51- if (v < 0 ) {
52- fill_leading_bits (leading_zeros ());
53- }
54- }
55- template <unsigned size, typename storageType>
56- template <typename U, typename EN>
57- constexpr MultiwordInteger<size, storageType>::MultiwordInteger(unsigned long long int v, typename EN::type *) {
58- *this = MultiwordInteger<size, storageType>((long long )v);
59- }
60- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(float v) : s{0 } {
61- if (v != 0 .) {
62- if (v > INT32_MIN && v < INT32_MAX) {
63- int32_t i = int32_t (v);
64- *this = i;
65- } else {
66- int lg = FixedPointHelpers::ilogb (v);
67- v *= FixedPointHelpers::dipow<float >(2 , 30 -lg);
68- *this = int64_t (v);
69- *this <<= lg - 30 ;
70- }
71- }
72- }
73- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(double v) : s{0 } {
74- if (v != 0 .) {
75- if (v > double (INT64_MIN) && v < double (INT64_MAX)) {
76- int64_t i = int64_t (v);
77- *this = i;
78- } else {
79- int lg = FixedPointHelpers::ilogb (v);
80- v *= FixedPointHelpers::dipow<double >(2 , 62 -lg);
81- *this = MultiwordInteger (int64_t (v));
82- *this <<= lg - 62 ;
83- }
84- }
85- }
86- template <unsigned size, typename storageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(long double v) : s{0 } {
87- if (v != 0 .) {
88- if (v > INT64_MIN && v < INT64_MAX) {
89- int64_t i = int64_t (v);
90- *this = i;
91- } else {
92- while (std::abs (v) >= 1 ) {
93- double tv = v;
94- MultiwordInteger<size, storageType> tmwi = tv;
95- *this += tmwi;
96- v -= tv;
97- }
98- }
99- }
100- }
101- template <unsigned size, typename storageType> template <unsigned otherSize, typename otherStorageType> constexpr MultiwordInteger<size, storageType>::MultiwordInteger(MultiwordInteger<otherSize, otherStorageType> const &o) : s{0 } {
36+
37+ template <unsigned size, typename storageType>
38+ template <unsigned otherSize, typename otherStorageType>
39+ constexpr MultiwordInteger<size, storageType>::MultiwordInteger(MultiwordInteger<otherSize, otherStorageType> const &o) : s{0 } {
10240 static_assert ((sizeof (storageType) % sizeof (otherStorageType)) == 0
10341 || (sizeof (otherStorageType) % sizeof (storageType)) == 0 ,
10442 " Types must fit into each other without remainder." );
@@ -155,4 +93,59 @@ template<unsigned size, typename storageType> template<unsigned otherSize, typen
15593 }
15694}
15795
96+ template <unsigned size, typename storageType>
97+ template <typename T>
98+ constexpr MultiwordInteger<size, storageType>::MultiwordInteger(T v) : s{0 } {
99+ static_assert (FixedPointHelpers::is_one_of<T, int8_t , int16_t , int32_t , int64_t , float , double , long double , unsigned long long >::value, " T must be a signed int or floating point type, or unsigned long long" );
100+ if constexpr (FixedPointHelpers::is_one_of<T, int8_t , int16_t , int32_t >::value) {
101+ *this = MultiwordInteger<size, typename std::make_unsigned<T>::type>(v);
102+ }
103+ else if constexpr (FixedPointHelpers::is_one_of<T, int64_t >::value) {
104+ uint64_t uv = v;
105+ unsigned i = 0 ;
106+ for (; i < size && uv; i++) {
107+ s[i] = uv;
108+ uv >>= storageSize;
109+ }
110+ for (; i < size; i++) {
111+ s[i] = 0 ;
112+ }
113+ if (v < 0 ) {
114+ fill_leading_bits (leading_zeros ());
115+ }
116+ }
117+ else if constexpr (FixedPointHelpers::is_one_of<T, float , double >::value) {
118+ if (v != 0 .) {
119+ using IntType = typename std::conditional<std::is_same<T, float >::value, int32_t , int64_t >::type;
120+ if (v > std::numeric_limits<IntType>::min () && v < std::numeric_limits<IntType>::max ()) {
121+ IntType i = IntType (v);
122+ *this = i;
123+ } else {
124+ int lg = FixedPointHelpers::ilogb (v);
125+ v *= FixedPointHelpers::dipow<T>(2 , sizeof (IntType)*8 -2 -lg);
126+ *this = MultiwordInteger (int64_t (v));
127+ *this <<= lg + 2 - sizeof (IntType)*8 ;
128+ }
129+ }
130+ }
131+ else if constexpr (FixedPointHelpers::is_one_of<T, long double >::value) {
132+ if (v != 0 .) {
133+ if (v > INT64_MIN && v < INT64_MAX) {
134+ int64_t i = int64_t (v);
135+ *this = i;
136+ } else {
137+ while (std::abs (v) >= 1 ) {
138+ double tv = v;
139+ MultiwordInteger<size, storageType> tmwi = tv;
140+ *this += tmwi;
141+ v -= tv;
142+ }
143+ }
144+ }
145+ }
146+ else if constexpr (FixedPointHelpers::is_one_of<T, unsigned long long >::value) {
147+ *this = MultiwordInteger<size, storageType>((long long )v);
148+ }
149+ }
150+
158151#endif // MULTIWORDINTEGERCONSTRUCTORS_HPP
0 commit comments