github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/common/int128_conversion.h (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 21 #pragma once 22 #include "common/common.h" 23 #include "common/math.h" 24 25 namespace neb { 26 27 namespace internal { 28 class int128_conversion_helper { 29 public: 30 inline int128_conversion_helper() { m_data.m_data = 0; } 31 inline int128_conversion_helper(const int128_t &data) { 32 m_data.m_data = data; 33 } 34 35 template <typename T> inline T to_float() { 36 T one = softfloat_cast<uint32_t, typename T::value_type>(1); 37 T limits = softfloat_cast<uint64_t, typename T::value_type>( 38 std::numeric_limits<uint64_t>::max()); 39 40 return T(m_data.m_detail.m_low) + 41 T(m_data.m_detail.m_high) * (limits + one); 42 } 43 44 template <typename T> inline int128_t from_float(const T &x) { 45 T one = softfloat_cast<uint32_t, typename T::value_type>(1); 46 T limits = softfloat_cast<uint64_t, typename T::value_type>( 47 std::numeric_limits<uint64_t>::max()); 48 49 if (x < limits) { 50 m_data.m_detail.m_low = 51 softfloat_cast<typename T::value_type, uint64_t>(x); 52 m_data.m_detail.m_high = 0; 53 return m_data.m_data; 54 } 55 56 m_data.m_detail.m_high = 57 softfloat_cast<typename T::value_type, int64_t>(x / (limits + one)); 58 m_data.m_detail.m_low = softfloat_cast<typename T::value_type, uint64_t>( 59 x - m_data.m_detail.m_high * (limits + one)); 60 return m_data.m_data; 61 } 62 63 inline const int128_t &data() const { return m_data.m_data; } 64 inline int128_t &data() { return m_data.m_data; } 65 66 inline const uint64_t &low() const { return m_data.m_detail.m_low; } 67 inline uint64_t &low() { return m_data.m_detail.m_low; } 68 69 inline const int64_t &high() const { return m_data.m_detail.m_high; } 70 inline int64_t &high() { return m_data.m_detail.m_high; } 71 72 private: 73 union _int128_t { 74 _int128_t() { m_data = 0; } 75 int128_t m_data; 76 struct _detail_t { 77 uint64_t m_low; 78 int64_t m_high; 79 }; 80 _detail_t m_detail; 81 }; 82 83 _int128_t m_data; 84 }; 85 } // namespace internal 86 87 template <typename T> inline T to_float(const int128_t &data) { 88 internal::int128_conversion_helper ch(data); 89 return ch.to_float<T>(); 90 } 91 template <typename T> inline int128_t from_float(const T &x) { 92 internal::int128_conversion_helper ch; 93 return ch.from_float(x); 94 } 95 96 } // namespace neb