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  }