@@ -191,22 +191,22 @@ namespace math::bid {
191191 if (exponent < -6176 || exponent > 6111 ) throw std::out_of_range (" Exponent out of Decimal128 range." );
192192 if (significand > max_significand) return zero;
193193 const std::uint64_t biased_exponent = static_cast <std::uint64_t >(exponent) + bias;
194- if ((significand.w [1 ] >> 49 ) == 0 ) return {significand.w [0 ], (significand.w [1 ] & 0x0001FFFFFFFFFFFFull ) | ((biased_exponent & 0x3fffull ) << 49 )}; // small finite branch: coefficient < 2^113
194+ if ((significand.w [1 ] >> 49 ) == 0 ) return {significand.w [0 ], (significand.w [1 ] & 0x0001FFFFFFFFFFFFull ) | ((biased_exponent & 0x3fffull ) << 49 )};
195+ // small finite branch: coefficient < 2^113
195196 return { significand.w [0 ], ((significand.w [1 ] & 0x00007FFFFFFFFFFFull )) | ((biased_exponent & 0x3fffull ) << 47 ) | (0x3ull << 61 )}; // large finite branch: coefficient has implicit leading 100...
196197 }
197198}
198199
199200namespace math {
200201 using uint128_t = BID_UINT128;
201-
202202 template <class T > struct bid_t {
203203 bid_t (T value) : value(value){}
204- operator T (){ return value; }
204+ operator T () const { return value; }
205205 T value;
206206 };
207207 template <class T > struct dpd_t {
208208 dpd_t (T value) : value(value){}
209- operator T (){ return value; }
209+ operator T () const { return value; }
210210 T value;
211211 };
212212 template <class T > struct decimal_t ;
@@ -221,7 +221,6 @@ namespace math {
221221 template <typename T> T str2bid (std::string_view);
222222 template <typename T> T str2bid (const std::string&);
223223 template <typename T> std::string bid2str (T);
224- template <typename T> std::pair<T,int16_t > decompose (T arg);
225224 template <typename T> T identity (T arg) { return arg; };
226225
227226 template <> uint32_t bid2dpd (uint32_t bid){ return __bid_to_dpd32 (bid); }
@@ -239,7 +238,7 @@ namespace math {
239238 template <> uint64_t bid2dpd (uint64_t bid){ return __bid_to_dpd64 (bid); }
240239 template <> uint64_t dpd2bid (uint64_t dpd){ return __bid_dpd_to_bid64 (dpd); }
241240 template <> uint64_t uint2bid (uint64_t significand, int exponent){ return bid::uint64_to_bid64 (significand, exponent); }
242- template <> uint64_t zero (){ return 0x31A0000000000000ULL ; }
241+ template <> uint64_t zero (){ return 0x31C0000000000000ULL ; }
243242 template <> long double bid2float<uint64_t , long double >(uint64_t bid){ unsigned int flags; return __bid64_to_binary80 (bid, 0 , &flags); }
244243 template <> uint64_t float2bid<float , uint64_t >(float bin){ unsigned int flags; return __binary32_to_bid64 (bin, 0 , &flags); }
245244 template <> uint64_t float2bid<double , uint64_t >(double bin){ unsigned int flags; return __binary64_to_bid64 (bin, 0 , &flags); }
@@ -262,55 +261,51 @@ namespace math {
262261 }
263262
264263 // operator defintions
265- #define sigma_unary_operator (_type, _op, _bid_fname ) decimal_t <_type> operator _op () { return decimal_t <_type>(_bid_fname (value)); }
266- #define sigma_arithmetic_operator (_type, _op, _bid_fname ) inline decimal_t <_type> operator _op (decimal_t <_type> lhs, decimal_t <_type> rhs) {\
264+ #define sigma_arithmetic_operator (_type, _op, _bid_fname ) inline decimal_t <_type> operator _op (decimal_t <_type> lhs, decimal_t <_type> rhs) { \
267265 unsigned int flags; return decimal_t <_type>::set (_bid_fname (lhs.value , rhs.value , 0 , &flags)); }
268266 #define sigma_comparison_operator (_type, _op, _bid_fname ) inline bool operator _op (decimal_t <_type> lhs, decimal_t <_type> rhs) {\
269267 unsigned int flags; return _bid_fname (lhs.value , rhs.value , &flags); }
270268
271- #define sigma_decimal_class (size, value_t, float_t ) \
272- template <> struct decimal_t <value_t > { \
273- decimal_t () : value(impl::zero<value_t >()){} \
274- decimal_t (value_t significand, int exponent) : value(impl::uint2bid<value_t >(significand, exponent)){} \
275- decimal_t (float_t bin) : value(impl::float2bid<float_t ,value_t >(bin)){} \
276- decimal_t (dpd_t <value_t > dpd) : value(impl::dpd2bid<value_t >(dpd)){} \
277- decimal_t (const char * ptr): value(impl::str2bid<value_t >(std::string_view{ptr})){} \
278- decimal_t (std::string_view str): value(impl::str2bid<value_t >(str)){} \
279- decimal_t (const std::string& str): value(impl::str2bid<value_t >(str)){} \
280- static decimal_t <value_t > from (float bin){ return decimal_t < value_t > (impl::float2bid<float , value_t >(bin));} \
281- static decimal_t <value_t > from (double bin){ return decimal_t < value_t > (impl::float2bid<double , value_t >(bin));} \
282- static decimal_t <value_t > from (long double bin){ return decimal_t < value_t > (impl::float2bid<long double , value_t >(bin));} \
283- static decimal_t <value_t > set (value_t value){ decimal_t decimal; decimal.value = value; return decimal;} \
284- explicit operator dpd_t <value_t >() const { return impl::bid2dpd<value_t >(this ->value ); } \
285- explicit operator bid_t <value_t >() const { return value; } \
286- explicit operator float_t () const { return impl::bid2float<value_t , float_t >(this ->value ); } \
287- operator std::string () const { return impl::bid2str (value); } \
288- operator std::pair <value_t , int16_t >() const { return impl::decompose (value); } \
289- decimal_t <value_t > operator +() const { return * this ; } \
290- sigma_unary_operator (uint##size##_t, +, impl::identity); \
291- sigma_unary_operator (uint##size##_t, -, __bid##size##_negate); \
292- value_t value; \
269+ #define sigma_decimal_class (size, value_t, float_t ) \
270+ template <> struct decimal_t <value_t > { \
271+ decimal_t () : value(impl::zero<value_t >()){} \
272+ decimal_t (value_t significand, int exponent) : value(impl::uint2bid<value_t >(significand, exponent)){} \
273+ decimal_t (float_t bin) : value(impl::float2bid<float_t ,value_t >(bin)){} \
274+ decimal_t (dpd_t <value_t > dpd) : value(impl::dpd2bid<value_t >(dpd)){} \
275+ decimal_t (const char * ptr): value(impl::str2bid<value_t >(std::string_view{ptr})){} \
276+ decimal_t (std::string_view str): value(impl::str2bid<value_t >(str)){} \
277+ decimal_t (const std::string& str): value(impl::str2bid<value_t >(str)){} \
278+ static decimal_t <value_t > from (float bin){ return set (impl::float2bid<float , value_t >(bin));} \
279+ static decimal_t <value_t > from (double bin){ return set (impl::float2bid<double , value_t >(bin));} \
280+ static decimal_t <value_t > from (long double bin){ return set (impl::float2bid<long double , value_t >(bin));} \
281+ static decimal_t <value_t > set (value_t value){ decimal_t decimal; decimal.value = value; return decimal;} \
282+ explicit operator dpd_t <value_t >() const { return impl::bid2dpd<value_t >(this ->value ); } \
283+ explicit operator bid_t <value_t >() const { return value; } \
284+ explicit operator float_t () const { return impl::bid2float<value_t , float_t >(this ->value ); } \
285+ operator std::string () const { return impl::bid2str (value); } \
286+ decimal_t <value_t >& operator +=( const decimal_t & rhs) { unsigned int flags; value = __bid##size## _add (value, rhs. value , 0 , &flags); return * this ; } \
287+ decimal_t <value_t >& operator -=( const decimal_t & rhs) { unsigned int flags; value = __bid##size## _sub (value, rhs. value , 0 , &flags); return * this ; } \
288+ decimal_t < value_t > operator +() const { return * this ; } \
289+ decimal_t < value_t > operator -() const { decimal_t < value_t > out; out. value = __bid##size##_negate (value ); return out; } \
290+ value_t value; \
293291 }
294292
295293 sigma_decimal_class (32 , uint32_t , double );
296294 sigma_decimal_class (64 , uint64_t , long double );
297295 sigma_decimal_class (128 , uint128_t , long double );
298-
299296 // operator combinations
300297 #define sigma_external_operators (_bit_size_ ) \
301298 sigma_arithmetic_operator (uint##_bit_size_##_t, +, __bid##_bit_size_##_add); sigma_arithmetic_operator(uint##_bit_size_##_t, -, __bid##_bit_size_##_sub); \
302299 sigma_arithmetic_operator (uint##_bit_size_##_t, *, __bid##_bit_size_##_mul); sigma_arithmetic_operator(uint##_bit_size_##_t, /, __bid##_bit_size_##_div); \
303300 sigma_comparison_operator (uint##_bit_size_##_t, ==, __bid##_bit_size_##_quiet_equal); sigma_comparison_operator(uint##_bit_size_##_t, !=, __bid##_bit_size_##_quiet_not_equal); \
304301 sigma_comparison_operator (uint##_bit_size_##_t, <, __bid##_bit_size_##_quiet_less); sigma_comparison_operator(uint##_bit_size_##_t, >, __bid##_bit_size_##_quiet_greater); \
305302 sigma_comparison_operator (uint##_bit_size_##_t, <=, __bid##_bit_size_##_quiet_less_equal); sigma_comparison_operator(uint##_bit_size_##_t, >=, __bid##_bit_size_##_quiet_greater_equal);
306-
307303 // operator instatiations for various bit sizes
308304 sigma_external_operators (32 ); sigma_external_operators(64 ); sigma_external_operators(128 );
309305 #undef sigma_external_operators
310306 #undef sigma_decimal_class
311307 #undef sigma_comparison_operator
312308 #undef sigma_arithmetic_operator
313- #undef sigma_unary_operator
314309
315310 #define sigma_decimal_literal (type, literal ) inline decimal_t <type> operator " " ##literal(const char * characters) { \
316311 std::string data (characters); \
@@ -325,16 +320,35 @@ namespace math {
325320 }
326321 #undef sigma_decimal_literal
327322 // begin utilities:
328- template <typename bid_t >
329- std::tuple<bool , bid_t , int16_t > decompose (decimal_t <bid_t > bid){
323+ template <typename bid_t > std::tuple<bool , bid_t , int16_t > decompose (decimal_t <bid_t > bid){
330324 auto [discriminant, mantissa, exponent] = bid::decompose (bid.value );
331325 switch (discriminant) {
332326 case bid::category::nan: throw std::runtime_error (" nan" );
333- case bid::category::pinf: return std::make_tuple (false , std::numeric_limits<bid_t >::max (), std::numeric_limits<uint16_t >::max ());
334- case bid::category::ninf: return std::make_tuple (true , std::numeric_limits<bid_t >::max (), std::numeric_limits<uint16_t >::max ());
327+ case bid::category::pinf: return std::make_tuple (false , std::numeric_limits<bid_t >::max (), std::numeric_limits<int16_t >::max ());
328+ case bid::category::ninf: return std::make_tuple (true , std::numeric_limits<bid_t >::max (), std::numeric_limits<int16_t >::max ());
335329 case bid::category::negative: return std::make_tuple (true , mantissa, exponent);
336330 case bid::category::positive: return std::make_tuple (false , mantissa, exponent);
337331 }
332+ #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
333+ std::unreachable ();
334+ #else
335+ throw std::runtime_error (" invalid decimal category" );
336+ #endif
337+ }
338+ template <> inline std::tuple<bool , BID_UINT128, int16_t > decompose (decimal_t <BID_UINT128> bid) {
339+ auto [discriminant, mantissa, exponent] = bid::decompose (bid.value );
340+ switch (discriminant) {
341+ case bid::category::nan: throw std::runtime_error (" nan" );
342+ case bid::category::pinf: return std::make_tuple (false , BID_UINT128{{~0ull , ~0ull }}, std::numeric_limits<int16_t >::max ());
343+ case bid::category::ninf: return std::make_tuple (true , BID_UINT128{{~0ull , ~0ull }}, std::numeric_limits<int16_t >::max ());
344+ case bid::category::negative: return std::make_tuple (true , to_bid128 (mantissa), exponent);
345+ case bid::category::positive: return std::make_tuple (false , to_bid128 (mantissa), exponent);
346+ }
347+ #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
348+ std::unreachable ();
349+ #else
350+ throw std::runtime_error (" invalid decimal category" );
351+ #endif
338352 }
339353 template <typename bid_t > bid_t mantissa (decimal_t <bid_t > bid) {
340354 auto [discriminant, mantissa, exponent] = bid::decompose (bid.value );
@@ -343,8 +357,16 @@ namespace math {
343357 case bid::category::pinf: throw std::runtime_error (" inexact exception: +inf" );
344358 case bid::category::ninf: throw std::runtime_error (" inexact exception: -inf" );
345359 case bid::category::negative: throw std::runtime_error (" attempting to convert negative value to unsigned" );
346- case bid::category::positive: return mantissa;
360+ case bid::category::positive:
361+ if constexpr (std::is_same_v<bid_t , BID_UINT128>)
362+ return to_bid128 (mantissa);
363+ else return mantissa;
347364 }
365+ #if defined(__cpp_lib_unreachable) && __cpp_lib_unreachable >= 202202L
366+ std::unreachable ();
367+ #else
368+ throw std::runtime_error (" invalid decimal category" );
369+ #endif
348370 }
349371 // end utilities
350372}
@@ -407,8 +429,6 @@ namespace math {
407429 #undef sigma_binary_op
408430}
409431// constants
410-
411-
412432namespace math {
413433 template <typename integral_type> struct constants ;
414434 template <> struct constants <uint32_t >{ // 7 digit precision
0 commit comments