/src/solidity/libsolutil/Numeric.h
Line | Count | Source |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * Definition of u256 and similar types and helper functions. |
20 | | */ |
21 | | |
22 | | #pragma once |
23 | | |
24 | | #include <libsolutil/Common.h> |
25 | | #include <libsolutil/CommonData.h> |
26 | | |
27 | | #include <boost/version.hpp> |
28 | | |
29 | | // TODO: do this only conditionally as soon as a boost version with gcc 12 support is released. |
30 | | #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12) |
31 | | #pragma GCC diagnostic push |
32 | | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" |
33 | | #pragma GCC diagnostic ignored "-Warray-bounds" |
34 | | #pragma GCC diagnostic ignored "-Wstringop-overread" |
35 | | #pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" |
36 | | #endif |
37 | | #include <boost/multiprecision/cpp_int.hpp> |
38 | | #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12) |
39 | | #pragma GCC diagnostic pop |
40 | | #endif |
41 | | |
42 | | #include <limits> |
43 | | |
44 | | namespace solidity |
45 | | { |
46 | | |
47 | | // Numeric types. |
48 | | using bigint = boost::multiprecision::cpp_int; |
49 | | using u256 = boost::multiprecision::uint256_t; |
50 | | using s256 = boost::multiprecision::int256_t; |
51 | | using u512 = boost::multiprecision::uint512_t; |
52 | | |
53 | | |
54 | | /// Interprets @a _u as a two's complement signed number and returns the resulting s256. |
55 | | inline s256 u2s(u256 _u) |
56 | 631k | { |
57 | 631k | static bigint const c_end = bigint(1) << 256; |
58 | 631k | if (boost::multiprecision::bit_test(_u, 255)) |
59 | 171k | return s256(-(c_end - _u)); |
60 | 459k | else |
61 | 459k | return s256(_u); |
62 | 631k | } |
63 | | |
64 | | /// @returns the two's complement signed representation of the signed number _u. |
65 | | inline u256 s2u(s256 _u) |
66 | 255k | { |
67 | 255k | static bigint const c_end = bigint(1) << 256; |
68 | 255k | if (_u >= 0) |
69 | 152k | return u256(_u); |
70 | 103k | else |
71 | 103k | return u256(c_end + _u); |
72 | 255k | } |
73 | | |
74 | | inline u256 exp256(u256 _base, u256 _exponent) |
75 | 54.4k | { |
76 | 54.4k | using boost::multiprecision::limb_type; |
77 | 54.4k | u256 result = 1; |
78 | 3.49M | while (_exponent) |
79 | 3.43M | { |
80 | 3.43M | if (boost::multiprecision::bit_test(_exponent, 0)) |
81 | 1.82M | result *= _base; |
82 | 3.43M | _base *= _base; |
83 | 3.43M | _exponent >>= 1; |
84 | 3.43M | } |
85 | 54.4k | return result; |
86 | 54.4k | } |
87 | | |
88 | | /// Checks whether _mantissa * (X ** _exp) fits into 4096 bits, |
89 | | /// where X is given indirectly via _log2OfBase = log2(X). |
90 | | bool fitsPrecisionBaseX(bigint const& _mantissa, double _log2OfBase, uint32_t _exp); |
91 | | |
92 | | |
93 | | // Big-endian to/from host endian conversion functions. |
94 | | |
95 | | /// Converts a templated integer value to the big-endian byte-stream represented on a templated collection. |
96 | | /// The size of the collection object will be unchanged. If it is too small, it will not represent the |
97 | | /// value properly, if too big then the additional elements will be zeroed out. |
98 | | /// @a Out will typically be either std::string or bytes. |
99 | | /// @a T will typically by unsigned, u160, u256 or bigint. |
100 | | template <class T, class Out> |
101 | | inline void toBigEndian(T _val, Out&& o_out) |
102 | 11.7M | { |
103 | 11.7M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift |
104 | 109M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) |
105 | 97.3M | { |
106 | 97.3M | T v = _val & (T)0xffu; |
107 | 97.3M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; |
108 | 97.3M | } |
109 | 11.7M | } void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 32ul>&>(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 32ul>&) Line | Count | Source | 102 | 766k | { | 103 | 766k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 25.2M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 24.5M | { | 106 | 24.5M | T v = _val & (T)0xffu; | 107 | 24.5M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 24.5M | } | 109 | 766k | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 102 | 5.04M | { | 103 | 5.04M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 64.5M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 59.4M | { | 106 | 59.4M | T v = _val & (T)0xffu; | 107 | 59.4M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 59.4M | } | 109 | 5.04M | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ul, 0ul, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ul, 0ul, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 102 | 3.38k | { | 103 | 3.38k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 107k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 104k | { | 106 | 104k | T v = _val & (T)0xffu; | 107 | 104k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 104k | } | 109 | 3.38k | } |
void solidity::toBigEndian<unsigned long, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(unsigned long, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 102 | 182k | { | 103 | 182k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 384k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 201k | { | 106 | 201k | T v = _val & (T)0xffu; | 107 | 201k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 201k | } | 109 | 182k | } |
void solidity::toBigEndian<unsigned int, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&>(unsigned int, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 102 | 44.3k | { | 103 | 44.3k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 96.3k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 51.9k | { | 106 | 51.9k | T v = _val & (T)0xffu; | 107 | 51.9k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 51.9k | } | 109 | 44.3k | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<8ul, 8ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 1ul>&>(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<8ul, 8ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 1ul>&) Line | Count | Source | 102 | 261k | { | 103 | 261k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 522k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 261k | { | 106 | 261k | T v = _val & (T)0xffu; | 107 | 261k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 261k | } | 109 | 261k | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, solidity::util::vector_ref<unsigned char> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, solidity::util::vector_ref<unsigned char>&&) Line | Count | Source | 102 | 3.00M | { | 103 | 3.00M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 10.7M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 7.74M | { | 106 | 7.74M | T v = _val & (T)0xffu; | 107 | 7.74M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 7.74M | } | 109 | 3.00M | } |
void solidity::toBigEndian<unsigned long, solidity::util::vector_ref<unsigned char>&>(unsigned long, solidity::util::vector_ref<unsigned char>&) Line | Count | Source | 102 | 2.39M | { | 103 | 2.39M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 104 | 7.37M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 4.97M | { | 106 | 4.97M | T v = _val & (T)0xffu; | 107 | 4.97M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 4.97M | } | 109 | 2.39M | } |
|
110 | | |
111 | | /// Converts a big-endian byte-stream represented on a templated collection to a templated integer value. |
112 | | /// @a In will typically be either std::string or bytes. |
113 | | /// @a T will typically by unsigned, u256 or bigint. |
114 | | template <class T, class In> |
115 | | inline T fromBigEndian(In const& _bytes) |
116 | 1.10M | { |
117 | 1.10M | T ret = (T)0; |
118 | 1.10M | for (auto i: _bytes) |
119 | 32.1M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); |
120 | 1.10M | return ret; |
121 | 1.10M | } boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> solidity::fromBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 32ul> >(std::__1::array<unsigned char, 32ul> const&) Line | Count | Source | 116 | 935k | { | 117 | 935k | T ret = (T)0; | 118 | 935k | for (auto i: _bytes) | 119 | 29.9M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 935k | return ret; | 121 | 935k | } |
boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<32ul, 32ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> solidity::fromBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<32ul, 32ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 4ul> >(std::__1::array<unsigned char, 4ul> const&) Line | Count | Source | 116 | 69.0k | { | 117 | 69.0k | T ret = (T)0; | 118 | 69.0k | for (auto i: _bytes) | 119 | 276k | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 69.0k | return ret; | 121 | 69.0k | } |
unsigned int solidity::fromBigEndian<unsigned int, solidity::util::vector_ref<unsigned char const> >(solidity::util::vector_ref<unsigned char const> const&) Line | Count | Source | 116 | 33 | { | 117 | 33 | T ret = (T)0; | 118 | 33 | for (auto i: _bytes) | 119 | 132 | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 33 | return ret; | 121 | 33 | } |
boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<160ul, 160ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> solidity::fromBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<160ul, 160ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 20ul> >(std::__1::array<unsigned char, 20ul> const&) Line | Count | Source | 116 | 95.9k | { | 117 | 95.9k | T ret = (T)0; | 118 | 95.9k | for (auto i: _bytes) | 119 | 1.91M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 95.9k | return ret; | 121 | 95.9k | } |
|
122 | 383k | inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; } |
123 | | |
124 | | /// Convenience function for toBigEndian. |
125 | | /// @returns a byte array just big enough to represent @a _val. |
126 | | template <class T> |
127 | | inline bytes toCompactBigEndian(T _val, unsigned _min = 0) |
128 | 4.89M | { |
129 | 4.89M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift |
130 | 4.89M | unsigned i = 0; |
131 | 52.1M | for (T v = _val; v; ++i, v >>= 8) {} |
132 | 4.89M | bytes ret(std::max<unsigned>(_min, i), 0); |
133 | 4.89M | toBigEndian(_val, ret); |
134 | 4.89M | return ret; |
135 | 4.89M | } std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ul, 0ul, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ul, 0ul, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, unsigned int) Line | Count | Source | 128 | 3.38k | { | 129 | 3.38k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 130 | 3.38k | unsigned i = 0; | 131 | 107k | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 3.38k | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 3.38k | toBigEndian(_val, ret); | 134 | 3.38k | return ret; | 135 | 3.38k | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, unsigned int) Line | Count | Source | 128 | 4.66M | { | 129 | 4.66M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 130 | 4.66M | unsigned i = 0; | 131 | 51.6M | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 4.66M | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 4.66M | toBigEndian(_val, ret); | 134 | 4.66M | return ret; | 135 | 4.66M | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<unsigned long>(unsigned long, unsigned int) Line | Count | Source | 128 | 182k | { | 129 | 182k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 130 | 182k | unsigned i = 0; | 131 | 365k | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 182k | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 182k | toBigEndian(_val, ret); | 134 | 182k | return ret; | 135 | 182k | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<unsigned int>(unsigned int, unsigned int) Line | Count | Source | 128 | 44.3k | { | 129 | 44.3k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 130 | 44.3k | unsigned i = 0; | 131 | 88.0k | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 44.3k | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 44.3k | toBigEndian(_val, ret); | 134 | 44.3k | return ret; | 135 | 44.3k | } |
|
136 | | |
137 | | /// Convenience function for conversion of a u256 to hex |
138 | | inline std::string toHex(u256 val) |
139 | 29.5k | { |
140 | 29.5k | return util::toHex(toBigEndian(val)); |
141 | 29.5k | } |
142 | | |
143 | | template <class T> |
144 | | inline std::string toCompactHexWithPrefix(T _value) |
145 | 2.57M | { |
146 | 2.57M | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); |
147 | 2.57M | } std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>) Line | Count | Source | 145 | 2.36M | { | 146 | 2.36M | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 147 | 2.36M | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<unsigned int>(unsigned int) Line | Count | Source | 145 | 44.3k | { | 146 | 44.3k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 147 | 44.3k | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<unsigned long>(unsigned long) Line | Count | Source | 145 | 165k | { | 146 | 165k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 147 | 165k | } |
|
148 | | |
149 | | /// Returns decimal representation for small numbers and hex for large numbers. |
150 | | inline std::string formatNumber(bigint const& _value) |
151 | 3.75k | { |
152 | 3.75k | if (_value < 0) |
153 | 0 | return "-" + formatNumber(-_value); |
154 | 3.75k | if (_value > 0x1000000) |
155 | 3.38k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); |
156 | 374 | else |
157 | 374 | return _value.str(); |
158 | 3.75k | } |
159 | | |
160 | | inline std::string formatNumber(u256 const& _value) |
161 | 3.80M | { |
162 | 3.80M | if (_value > 0x1000000) |
163 | 1.23M | return toCompactHexWithPrefix(_value); |
164 | 2.56M | else |
165 | 2.56M | return _value.str(); |
166 | 3.80M | } |
167 | | |
168 | | |
169 | | // Algorithms for string and string-like collections. |
170 | | |
171 | | /// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero. |
172 | | template <class T> |
173 | | inline unsigned numberEncodingSize(T _i) |
174 | 66.5M | { |
175 | 66.5M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift |
176 | 66.5M | unsigned i = 0; |
177 | 371M | for (; _i != 0; ++i, _i >>= 8) {} |
178 | 66.5M | return i; |
179 | 66.5M | } unsigned int solidity::numberEncodingSize<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ul, 0ul, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0ul, 0ul, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>) Line | Count | Source | 174 | 295k | { | 175 | 295k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 176 | 295k | unsigned i = 0; | 177 | 1.42M | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 295k | return i; | 179 | 295k | } |
unsigned int solidity::numberEncodingSize<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256ul, 256ul, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>) Line | Count | Source | 174 | 62.4M | { | 175 | 62.4M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 176 | 62.4M | unsigned i = 0; | 177 | 359M | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 62.4M | return i; | 179 | 62.4M | } |
unsigned int solidity::numberEncodingSize<unsigned long>(unsigned long) Line | Count | Source | 174 | 3.64M | { | 175 | 3.64M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 176 | 3.64M | unsigned i = 0; | 177 | 10.5M | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 3.64M | return i; | 179 | 3.64M | } |
unsigned int solidity::numberEncodingSize<unsigned int>(unsigned int) Line | Count | Source | 174 | 156k | { | 175 | 156k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 176 | 156k | unsigned i = 0; | 177 | 365k | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 156k | return i; | 179 | 156k | } |
|
180 | | |
181 | | } |