ethereum.utils.numeric
Utility Functions For Numeric Operations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. contents:: Table of Contents :backlinks: none :local:
Introduction
Numeric operations specific utility functions used in this specification.
get_sign
Determines the sign of a number.
Parameters
value : The value whose sign is to be determined.
Returns
sign : int
The sign of the number (-1 or 0 or 1).
The return value is based on math signum function.
def get_sign(value: int) -> int:
20 | """ |
---|---|
21 | Determines the sign of a number. |
22 |
|
23 | Parameters |
24 | ---------- |
25 | value : |
26 | The value whose sign is to be determined. |
27 |
|
28 | Returns |
29 | ------- |
30 | sign : `int` |
31 | The sign of the number (-1 or 0 or 1). |
32 | The return value is based on math signum function. |
33 | """ |
34 | if value < 0: |
35 | return -1 |
36 | elif value == 0: |
37 | return 0 |
38 | else: |
39 | return 1 |
ceil32
Converts a unsigned integer to the next closest multiple of 32.
Parameters
value : The value whose ceil32 is to be calculated.
Returns
ceil32 : ethereum.base_types.U256
The same value if it's a perfect multiple of 32
else it returns the smallest multiple of 32
that is greater than value
.
def ceil32(value: Uint) -> Uint:
43 | """ |
---|---|
44 | Converts a unsigned integer to the next closest multiple of 32. |
45 |
|
46 | Parameters |
47 | ---------- |
48 | value : |
49 | The value whose ceil32 is to be calculated. |
50 |
|
51 | Returns |
52 | ------- |
53 | ceil32 : `ethereum.base_types.U256` |
54 | The same value if it's a perfect multiple of 32 |
55 | else it returns the smallest multiple of 32 |
56 | that is greater than `value`. |
57 | """ |
58 | ceiling = Uint(32) |
59 | remainder = value % ceiling |
60 | if remainder == Uint(0): |
61 | return value |
62 | else: |
63 | return value + ceiling - remainder |
is_prime
Checks if number
is a prime number.
Parameters
number : The number to check for primality.
Returns
is_number_prime : bool
Boolean indicating if number
is prime or not.
def is_prime(number: SupportsInt) -> bool:
67 | """ |
---|---|
68 | Checks if `number` is a prime number. |
69 |
|
70 | Parameters |
71 | ---------- |
72 | number : |
73 | The number to check for primality. |
74 |
|
75 | Returns |
76 | ------- |
77 | is_number_prime : `bool` |
78 | Boolean indicating if `number` is prime or not. |
79 | """ |
80 | number = int(number) |
81 | if number <= 1: |
82 | return False |
83 | |
84 | # number ** 0.5 is faster than math.sqrt(number) |
85 | for x in range(2, int(number**0.5) + 1): |
86 | # Return False if number is divisible by x |
87 | if number % x == 0: |
88 | return False |
89 | |
90 | return True |
le_bytes_to_uint32_sequence
Convert little endian byte stream data
to a little endian U32
sequence i.e., the first U32 number of the sequence is the least
significant U32 number.
Parameters
data : The byte stream (little endian) which is to be converted to a U32 stream.
Returns
uint32_sequence : Tuple[U32, ...]
Sequence of U32 numbers obtained from the little endian byte
stream.
def le_bytes_to_uint32_sequence(data: bytes) -> Tuple[U32, ...]:
94 | """ |
---|---|
95 | Convert little endian byte stream `data` to a little endian U32 |
96 | sequence i.e., the first U32 number of the sequence is the least |
97 | significant U32 number. |
98 |
|
99 | Parameters |
100 | ---------- |
101 | data : |
102 | The byte stream (little endian) which is to be converted to a U32 |
103 | stream. |
104 |
|
105 | Returns |
106 | ------- |
107 | uint32_sequence : `Tuple[U32, ...]` |
108 | Sequence of U32 numbers obtained from the little endian byte |
109 | stream. |
110 | """ |
111 | sequence = [] |
112 | for i in range(0, len(data), 4): |
113 | sequence.append(U32.from_le_bytes(data[i : i + 4])) |
114 | |
115 | return tuple(sequence) |
le_uint32_sequence_to_bytes
Obtain little endian byte stream from a little endian U32 sequence i.e., the first U32 number of the sequence is the least significant U32 number.
Note - In this conversion, the most significant byte (byte at the end of the little endian stream) may have leading zeroes. This function doesn't take care of removing these leading zeroes as shown in below example.
le_uint32_sequence_to_bytes([U32(8)]) b'\x08\x00\x00\x00'
Parameters
sequence : The U32 stream (little endian) which is to be converted to a little endian byte stream.
Returns
result : bytes
The byte stream obtained from the little endian U32 stream.
def le_uint32_sequence_to_bytes(sequence: Sequence[U32]) -> bytes:
119 | r""" |
---|---|
120 | Obtain little endian byte stream from a little endian U32 sequence |
121 | i.e., the first U32 number of the sequence is the least significant |
122 | U32 number. |
123 |
|
124 | Note - In this conversion, the most significant byte (byte at the end of |
125 | the little endian stream) may have leading zeroes. This function doesn't |
126 | take care of removing these leading zeroes as shown in below example. |
127 |
|
128 | >>> le_uint32_sequence_to_bytes([U32(8)]) |
129 | b'\x08\x00\x00\x00' |
130 |
|
131 |
|
132 | Parameters |
133 | ---------- |
134 | sequence : |
135 | The U32 stream (little endian) which is to be converted to a |
136 | little endian byte stream. |
137 |
|
138 | Returns |
139 | ------- |
140 | result : `bytes` |
141 | The byte stream obtained from the little endian U32 stream. |
142 | """ |
143 | result_bytes = b"" |
144 | for item in sequence: |
145 | result_bytes += item.to_le_bytes4() |
146 | |
147 | return result_bytes |
le_uint32_sequence_to_uint
Obtain Uint from a U32 sequence assuming that this sequence is little endian i.e., the first U32 number of the sequence is the least significant U32 number.
Parameters
sequence : The U32 stream (little endian) which is to be converted to a Uint.
Returns
value : Uint
The Uint number obtained from the conversion of the little endian
U32 stream.
def le_uint32_sequence_to_uint(sequence: Sequence[U32]) -> Uint:
151 | """ |
---|---|
152 | Obtain Uint from a U32 sequence assuming that this sequence is little |
153 | endian i.e., the first U32 number of the sequence is the least |
154 | significant U32 number. |
155 |
|
156 | Parameters |
157 | ---------- |
158 | sequence : |
159 | The U32 stream (little endian) which is to be converted to a Uint. |
160 |
|
161 | Returns |
162 | ------- |
163 | value : `Uint` |
164 | The Uint number obtained from the conversion of the little endian |
165 | U32 stream. |
166 | """ |
167 | sequence_as_bytes = le_uint32_sequence_to_bytes(sequence) |
168 | return Uint.from_le_bytes(sequence_as_bytes) |
taylor_exponential
Approximates factor * e ** (numerator / denominator) using Taylor expansion.
Parameters
factor : The factor. numerator : The numerator of the exponential. denominator : The denominator of the exponential.
Returns
output : ethereum.base_types.Uint
The approximation of factor * e ** (numerator / denominator).
def taylor_exponential(factor: Uint, numerator: Uint, denominator: Uint) -> Uint:
174 | """ |
---|---|
175 | Approximates factor * e ** (numerator / denominator) using |
176 | Taylor expansion. |
177 |
|
178 | Parameters |
179 | ---------- |
180 | factor : |
181 | The factor. |
182 | numerator : |
183 | The numerator of the exponential. |
184 | denominator : |
185 | The denominator of the exponential. |
186 |
|
187 | Returns |
188 | ------- |
189 | output : `ethereum.base_types.Uint` |
190 | The approximation of factor * e ** (numerator / denominator). |
191 |
|
192 | """ |
193 | i = Uint(1) |
194 | output = Uint(0) |
195 | numerator_accumulated = factor * denominator |
196 | while numerator_accumulated > Uint(0): |
197 | output += numerator_accumulated |
198 | numerator_accumulated = (numerator_accumulated * numerator) // ( |
199 | denominator * i |
200 | ) |
201 | i += Uint(1) |
202 | return output // denominator |