github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/test/common/gtest_conversion.cpp (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 #include "common/int128_conversion.h" 22 #include <gtest/gtest.h> 23 #include <random> 24 25 #define PRECESION 1e-5 26 template <typename T> T precesion(const T &x, float pre = PRECESION) { 27 return std::fabs(T(x * pre)); 28 } 29 30 TEST(test_common_conversion, basic) { 31 neb::internal::int128_conversion_helper cv; 32 EXPECT_EQ(cv.data(), 0); 33 EXPECT_EQ(cv.high(), 0); 34 EXPECT_EQ(cv.low(), 0); 35 36 neb::int128_t data = boost::lexical_cast<neb::int128_t>("0"); 37 neb::internal::int128_conversion_helper cv_0(data); 38 EXPECT_EQ(cv_0.data(), 0); 39 EXPECT_EQ(cv_0.high(), 0); 40 EXPECT_EQ(cv_0.low(), 0); 41 42 data = boost::lexical_cast<neb::int128_t>("1"); 43 neb::internal::int128_conversion_helper cv_1(data); 44 EXPECT_EQ(cv_1.data(), 1); 45 EXPECT_EQ(cv_1.high(), 0); 46 EXPECT_EQ(cv_1.low(), 1); 47 48 int64_t high = 1; 49 uint64_t low = 1; 50 neb::internal::int128_conversion_helper tmp; 51 tmp.high() = high; 52 tmp.low() = low; 53 EXPECT_EQ(tmp.data(), 54 boost::lexical_cast<neb::int128_t>("18446744073709551617")); 55 neb::internal::int128_conversion_helper cv_3(tmp.data()); 56 EXPECT_EQ(cv_3.data(), tmp.data()); 57 EXPECT_EQ(cv_3.high(), tmp.high()); 58 EXPECT_EQ(cv_3.low(), tmp.low()); 59 60 high = 123456; 61 low = 456789; 62 tmp.high() = high; 63 tmp.low() = low; 64 EXPECT_EQ(tmp.data(), 65 boost::lexical_cast<neb::int128_t>("2277361236363886404761685")); 66 neb::internal::int128_conversion_helper cv_4(tmp.data()); 67 EXPECT_EQ(cv_4.data(), tmp.data()); 68 EXPECT_EQ(cv_4.high(), tmp.high()); 69 EXPECT_EQ(cv_4.low(), tmp.low()); 70 } 71 72 TEST(test_common_conversion, to_float) { 73 neb::internal::int128_conversion_helper cv; 74 auto f_data = cv.to_float<neb::floatxx_t>(); 75 EXPECT_EQ(f_data, 0); 76 77 auto data = boost::lexical_cast<neb::int128_t>("1"); 78 neb::internal::int128_conversion_helper cv_1(data); 79 f_data = cv_1.to_float<neb::floatxx_t>(); 80 EXPECT_EQ(f_data, 1); 81 82 int64_t high = 1; 83 uint64_t low = 1; 84 neb::internal::int128_conversion_helper tmp; 85 tmp.high() = high; 86 tmp.low() = low; 87 neb::internal::int128_conversion_helper cv_3(tmp.data()); 88 f_data = cv_3.to_float<neb::floatxx_t>(); 89 std::ostringstream oss; 90 oss << boost::lexical_cast<float>(tmp.data()); 91 EXPECT_EQ(oss.str(), std::string("1.84467e+19")); 92 EXPECT_EQ(neb::math::to_string(f_data), oss.str()); 93 94 high = 123456; 95 low = 456789; 96 tmp.high() = high; 97 tmp.low() = low; 98 neb::internal::int128_conversion_helper cv_4(tmp.data()); 99 f_data = cv_4.to_float<neb::floatxx_t>(); 100 oss.str(std::string()); 101 oss << boost::lexical_cast<float>(tmp.data()); 102 EXPECT_EQ(oss.str(), std::string("2.27736e+24")); 103 EXPECT_EQ(neb::math::to_string(f_data), oss.str()); 104 105 std::random_device rd; 106 std::mt19937 mt(rd()); 107 std::uniform_int_distribution<> dis(0, std::numeric_limits<int32_t>::max()); 108 for (auto i = 0; i < 1000; i++) { 109 high = dis(mt); 110 low = dis(mt); 111 tmp.high() = high; 112 tmp.low() = low; 113 neb::internal::int128_conversion_helper cv(tmp.data()); 114 f_data = cv.to_float<neb::floatxx_t>(); 115 oss.str(std::string()); 116 oss << boost::lexical_cast<float>(tmp.data()); 117 EXPECT_EQ(neb::math::to_string(f_data), oss.str()); 118 } 119 } 120 121 TEST(test_common_conversion, from_float) { 122 uint64_t x = 0; 123 float y = x; 124 neb::internal::int128_conversion_helper cv; 125 EXPECT_EQ(cv.from_float(neb::floatxx_t(y)), 0); 126 127 x = 1; 128 y = x; 129 EXPECT_EQ(cv.from_float(neb::floatxx_t(y)), 1); 130 131 x = 10000000000ULL; 132 y = x; 133 y = y * x; 134 auto actual_y = cv.from_float(neb::floatxx_t(y)); 135 auto expect_y = boost::lexical_cast<neb::int128_t>("100000000000000000000"); 136 EXPECT_TRUE(boost::lexical_cast<float>(neb::math::abs(actual_y, expect_y)) < 137 precesion(y, 1e-6)); 138 139 x = 12345600000ULL; 140 y = x; 141 y = y * 1e15; 142 actual_y = cv.from_float(neb::floatxx_t(y)); 143 expect_y = boost::lexical_cast<neb::int128_t>("12345600000000000000000000"); 144 EXPECT_TRUE(boost::lexical_cast<float>(neb::math::abs(actual_y, expect_y)) < 145 precesion(y, 1e-6)); 146 147 x = 45678900000ULL; 148 y = x; 149 y = y * 1e20; 150 actual_y = cv.from_float(neb::floatxx_t(y)); 151 expect_y = 152 boost::lexical_cast<neb::int128_t>("4567890000000000000000000000000"); 153 EXPECT_TRUE(boost::lexical_cast<float>(neb::math::abs(actual_y, expect_y)) < 154 precesion(y, 1e-6)); 155 156 std::random_device rd; 157 std::mt19937 mt(rd()); 158 std::uniform_int_distribution<> dis(0, std::numeric_limits<int32_t>::max()); 159 for (auto i = 0; i < 1000; i++) { 160 x = dis(mt); 161 y = x; 162 expect_y = x; 163 x = dis(mt); 164 y = y * x; 165 expect_y = expect_y * x; 166 actual_y = cv.from_float(neb::floatxx_t(y)); 167 EXPECT_TRUE(boost::lexical_cast<float>(neb::math::abs(actual_y, expect_y)) < 168 precesion(y, 1e-6)); 169 } 170 }