Handle `integer_squareroot` bound case

This commit is contained in:
Hsiao-Wei Wang 2024-02-14 17:18:05 +08:00
parent daf6a0af45
commit 7076fb2b75
No known key found for this signature in database
GPG Key ID: AE3D6B174F971DE4
3 changed files with 26 additions and 0 deletions

View File

@ -178,6 +178,7 @@ The following values are (non-configurable) constants used throughout the specif
| Name | Value |
| - | - |
| `MAX_UINT_64` | `uint64(2**64 - 1)` |
| `GENESIS_SLOT` | `Slot(0)` |
| `GENESIS_EPOCH` | `Epoch(0)` |
| `FAR_FUTURE_EPOCH` | `Epoch(2**64 - 1)` |
@ -599,6 +600,8 @@ def integer_squareroot(n: uint64) -> uint64:
"""
Return the largest integer ``x`` such that ``x**2 <= n``.
"""
if n == MAX_UINT_64:
return uint64(4294967295)
x = n
y = (x + 1) // 2
while y < x:

View File

@ -0,0 +1,23 @@
import random
from math import isqrt
from eth2spec.test.context import (
spec_test,
single_phase,
with_all_phases,
)
@with_all_phases
@spec_test
@single_phase
def test_integer_squareroot(spec):
values = [0, 100, 2**64 - 2, 2**64 - 1]
for n in values:
uint64_n = spec.uint64(n)
assert spec.integer_squareroot(uint64_n) == isqrt(n)
rng = random.Random(5566)
for _ in range(10):
n = rng.randint(0, 2**64 - 1)
uint64_n = spec.uint64(n)
assert spec.integer_squareroot(uint64_n) == isqrt(n)