/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 | 576k | { |
57 | 576k | static bigint const c_end = bigint(1) << 256; |
58 | 576k | if (boost::multiprecision::bit_test(_u, 255)) |
59 | 160k | return s256(-(c_end - _u)); |
60 | 415k | else |
61 | 415k | return s256(_u); |
62 | 576k | } |
63 | | |
64 | | /// @returns the two's complement signed representation of the signed number _u. |
65 | | inline u256 s2u(s256 _u) |
66 | 231k | { |
67 | 231k | static bigint const c_end = bigint(1) << 256; |
68 | 231k | if (_u >= 0) |
69 | 135k | return u256(_u); |
70 | 95.8k | else |
71 | 95.8k | return u256(c_end + _u); |
72 | 231k | } |
73 | | |
74 | | inline u256 exp256(u256 _base, u256 _exponent) |
75 | 52.1k | { |
76 | 52.1k | using boost::multiprecision::limb_type; |
77 | 52.1k | u256 result = 1; |
78 | 3.01M | while (_exponent) |
79 | 2.96M | { |
80 | 2.96M | if (boost::multiprecision::bit_test(_exponent, 0)) |
81 | 1.52M | result *= _base; |
82 | 2.96M | _base *= _base; |
83 | 2.96M | _exponent >>= 1; |
84 | 2.96M | } |
85 | 52.1k | return result; |
86 | 52.1k | } |
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 | 10.7M | { |
103 | 10.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 | 100M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) |
105 | 90.0M | { |
106 | 90.0M | T v = _val & (T)0xffu; |
107 | 90.0M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; |
108 | 90.0M | } |
109 | 10.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 | 748k | { | 103 | 748k | 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 | 24.6M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 23.9M | { | 106 | 23.9M | T v = _val & (T)0xffu; | 107 | 23.9M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 23.9M | } | 109 | 748k | } |
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 | 4.72M | { | 103 | 4.72M | 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 | 59.0M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 54.3M | { | 106 | 54.3M | T v = _val & (T)0xffu; | 107 | 54.3M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 54.3M | } | 109 | 4.72M | } |
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.16k | { | 103 | 3.16k | 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 | 100k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 97.2k | { | 106 | 97.2k | T v = _val & (T)0xffu; | 107 | 97.2k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 97.2k | } | 109 | 3.16k | } |
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 | 166k | { | 103 | 166k | 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 | 349k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 183k | { | 106 | 183k | T v = _val & (T)0xffu; | 107 | 183k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 183k | } | 109 | 166k | } |
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 | 38.6k | { | 103 | 38.6k | 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 | 82.8k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 44.2k | { | 106 | 44.2k | T v = _val & (T)0xffu; | 107 | 44.2k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 44.2k | } | 109 | 38.6k | } |
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 | 203k | { | 103 | 203k | 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 | 406k | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 203k | { | 106 | 203k | T v = _val & (T)0xffu; | 107 | 203k | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 203k | } | 109 | 203k | } |
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 | 2.65M | { | 103 | 2.65M | 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 | 9.40M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 6.75M | { | 106 | 6.75M | T v = _val & (T)0xffu; | 107 | 6.75M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 6.75M | } | 109 | 2.65M | } |
void solidity::toBigEndian<unsigned long, solidity::util::vector_ref<unsigned char>&>(unsigned long, solidity::util::vector_ref<unsigned char>&) Line | Count | Source | 102 | 2.16M | { | 103 | 2.16M | 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 | 6.62M | for (auto i = o_out.size(); i != 0u; _val >>= 8u, i--) | 105 | 4.46M | { | 106 | 4.46M | T v = _val & (T)0xffu; | 107 | 4.46M | o_out[i - 1u] = (typename std::remove_reference_t<Out>::value_type)(uint8_t)v; | 108 | 4.46M | } | 109 | 2.16M | } |
|
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.07M | { |
117 | 1.07M | T ret = (T)0; |
118 | 1.07M | for (auto i: _bytes) |
119 | 31.4M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); |
120 | 1.07M | return ret; |
121 | 1.07M | } 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 | 916k | { | 117 | 916k | T ret = (T)0; | 118 | 916k | for (auto i: _bytes) | 119 | 29.3M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 916k | return ret; | 121 | 916k | } |
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 | 65.1k | { | 117 | 65.1k | T ret = (T)0; | 118 | 65.1k | for (auto i: _bytes) | 119 | 260k | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 65.1k | return ret; | 121 | 65.1k | } |
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 | 92.7k | { | 117 | 92.7k | T ret = (T)0; | 118 | 92.7k | for (auto i: _bytes) | 119 | 1.85M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 120 | 92.7k | return ret; | 121 | 92.7k | } |
|
122 | 329k | 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.60M | { |
129 | 4.60M | 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.60M | unsigned i = 0; |
131 | 48.4M | for (T v = _val; v; ++i, v >>= 8) {} |
132 | 4.60M | bytes ret(std::max<unsigned>(_min, i), 0); |
133 | 4.60M | toBigEndian(_val, ret); |
134 | 4.60M | return ret; |
135 | 4.60M | } 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.16k | { | 129 | 3.16k | 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.16k | unsigned i = 0; | 131 | 100k | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 3.16k | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 3.16k | toBigEndian(_val, ret); | 134 | 3.16k | return ret; | 135 | 3.16k | } |
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.39M | { | 129 | 4.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 | 130 | 4.39M | unsigned i = 0; | 131 | 47.9M | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 4.39M | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 4.39M | toBigEndian(_val, ret); | 134 | 4.39M | return ret; | 135 | 4.39M | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<unsigned long>(unsigned long, unsigned int) Line | Count | Source | 128 | 166k | { | 129 | 166k | 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 | 166k | unsigned i = 0; | 131 | 331k | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 166k | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 166k | toBigEndian(_val, ret); | 134 | 166k | return ret; | 135 | 166k | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<unsigned int>(unsigned int, unsigned int) Line | Count | Source | 128 | 38.6k | { | 129 | 38.6k | 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 | 38.6k | unsigned i = 0; | 131 | 75.3k | for (T v = _val; v; ++i, v >>= 8) {} | 132 | 38.6k | bytes ret(std::max<unsigned>(_min, i), 0); | 133 | 38.6k | toBigEndian(_val, ret); | 134 | 38.6k | return ret; | 135 | 38.6k | } |
|
136 | | |
137 | | /// Convenience function for conversion of a u256 to hex |
138 | | inline std::string toHex(u256 val) |
139 | 24.9k | { |
140 | 24.9k | return util::toHex(toBigEndian(val)); |
141 | 24.9k | } |
142 | | |
143 | | template <class T> |
144 | | inline std::string toCompactHexWithPrefix(T _value) |
145 | 2.46M | { |
146 | 2.46M | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); |
147 | 2.46M | } 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.27M | { | 146 | 2.27M | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 147 | 2.27M | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<unsigned int>(unsigned int) Line | Count | Source | 145 | 38.6k | { | 146 | 38.6k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 147 | 38.6k | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<unsigned long>(unsigned long) Line | Count | Source | 145 | 149k | { | 146 | 149k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 147 | 149k | } |
|
148 | | |
149 | | /// Returns decimal representation for small numbers and hex for large numbers. |
150 | | inline std::string formatNumber(bigint const& _value) |
151 | 3.45k | { |
152 | 3.45k | if (_value < 0) |
153 | 0 | return "-" + formatNumber(-_value); |
154 | 3.45k | if (_value > 0x1000000) |
155 | 3.16k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); |
156 | 296 | else |
157 | 296 | return _value.str(); |
158 | 3.45k | } |
159 | | |
160 | | inline std::string formatNumber(u256 const& _value) |
161 | 3.46M | { |
162 | 3.46M | if (_value > 0x1000000) |
163 | 1.12M | return toCompactHexWithPrefix(_value); |
164 | 2.33M | else |
165 | 2.33M | return _value.str(); |
166 | 3.46M | } |
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 | 57.3M | { |
175 | 57.3M | 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 | 57.3M | unsigned i = 0; |
177 | 313M | for (; _i != 0; ++i, _i >>= 8) {} |
178 | 57.3M | return i; |
179 | 57.3M | } 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 | 259k | { | 175 | 259k | 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 | 259k | unsigned i = 0; | 177 | 1.23M | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 259k | return i; | 179 | 259k | } |
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 | 53.6M | { | 175 | 53.6M | 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 | 53.6M | unsigned i = 0; | 177 | 302M | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 53.6M | return i; | 179 | 53.6M | } |
unsigned int solidity::numberEncodingSize<unsigned long>(unsigned long) Line | Count | Source | 174 | 3.29M | { | 175 | 3.29M | 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.29M | unsigned i = 0; | 177 | 9.53M | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 3.29M | return i; | 179 | 3.29M | } |
unsigned int solidity::numberEncodingSize<unsigned int>(unsigned int) Line | Count | Source | 174 | 148k | { | 175 | 148k | 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 | 148k | unsigned i = 0; | 177 | 345k | for (; _i != 0; ++i, _i >>= 8) {} | 178 | 148k | return i; | 179 | 148k | } |
|
180 | | |
181 | | } |