From ed380f713cbb8ebb28a5ea3deb4cd7f9bd72d4cc Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 12:57:25 +0530 Subject: [PATCH 01/12] init --- sway-lib-std/src/u128.sw | 61 ++++- .../u128_inline_tests/src/main.sw | 243 ++++++++++++++++++ 2 files changed, 300 insertions(+), 4 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 94a27c98027..d13147f6980 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -3,7 +3,13 @@ library; use ::assert::assert; use ::convert::{From, Into}; -use ::flags::{disable_panic_on_overflow, set_flags}; +use ::flags::{ + disable_panic_on_overflow, + panic_on_overflow_enabled, + panic_on_unsafe_math_enabled, + set_flags, +}; +use ::registers::{flags, overflow}; use ::math::*; use ::result::Result::{self, *}; @@ -713,8 +719,10 @@ impl BinaryLogarithm for U128 { fn log2(self) -> Self { let zero = Self::from((0, 0)); let mut res = zero; - // If trying to get a log2(0), panic, as infinity is not a number. - assert(self != zero); + // If panic on unsafe math is enabled, only then revert + if panic_on_unsafe_math_enabled() { + assert(self != zero); + } if self.upper != 0 { res = Self::from((0, self.upper.log(2) + 64)); } else if self.lower != 0 { @@ -726,8 +734,53 @@ impl BinaryLogarithm for U128 { impl Logarithm for U128 { fn log(self, base: Self) -> Self { + let flags = disable_panic_on_overflow(); + + // If panic on unsafe math is enabled, only then revert + if panic_on_unsafe_math_enabled() { + // Logarithm is undefined for bases less than 2 + assert(base >= 2); + // Logarithm is undefined for 0 + assert(self != 0); + } + + // Decimals rounded to 0 + if self < base { + return 0x00u256; + } + + // Estimating the result using change of base formula. Only an estimate because we are doing uint calculations. let self_log2 = self.log2(); let base_log2 = base.log2(); - self_log2 / base_log2 + let mut result = (self_log2 / base_log2); + + // Converting u128 to u32, this cannot fail as the result will be atmost ~128 + let parts: (u64, u64) = result.into(); + let res_u32 = asm(r1: parts.1) { + r1: u32 + }; + + // Raising the base to the power of the result + let mut pow_res = base.pow(res_u32); + let mut of = overflow(); + + // Adjusting the result until the power is less than or equal to self + // If pow_res is > than self, then there is an overestimation. If there is an overflow then there is definitely an overestimation. + while (pow_res > self) || (of > 0) { + result -= 1; + + // Converting u128 to u32, this cannot fail as the result will be atmost ~128 + let parts: (u64, u64) = result.into(); + let res_u32 = asm(r1: parts.1) { + r1: u32 + }; + + pow_res = base.pow(res_u32); + of = overflow(); + }; + + set_flags(flags); + + result } } diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index c7fc8405215..bdc5ef5812b 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -742,3 +742,246 @@ fn revert_u128_binary_log() { let _result = u_128_0.log2(); } + +#[test] +fn parity_u128_log_with_ruint() { + // Failure cases found by comparing parity with ruint implementation of U128 + // https://docs.rs/ruint/latest/src/ruint/log.rs.html#45-89 + let a = [ + 2, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 29, + 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 60, 60, + 60, 60, 61, 61, 61, 62, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, + 100, 100, 100, 100, + ]; + let b = [ + 3, 3, 5, 6, 7, 3, 6, 7, 3, 7, 3, 3, 9, 10, 11, 12, 13, 14, 15, 3, 10, 11, 12, 13, 14, 15, + 3, 11, 12, 13, 14, 15, 3, 12, 13, 14, 15, 3, 13, 14, 15, 3, 14, 15, 3, 15, 3, 3, 5, 6, 7, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 3, 5, 6, 7, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, + 6, 7, 23, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31, 3, 5, + 6, 7, 25, 26, 27, 28, 29, 30, 31, 3, 6, 7, 26, 27, 28, 29, 30, 31, 3, 6, 7, 27, 28, 29, 30, + 31, 3, 6, 7, 28, 29, 30, 31, 3, 6, 7, 29, 30, 31, 3, 6, 7, 30, 31, 3, 6, 7, 31, 3, 6, 7, 3, + 6, 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 6, 7, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 6, 7, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 3, 6, 7, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 3, 7, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 3, 7, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 3, 7, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 3, 7, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 7, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 3, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 55, 56, 57, 58, 59, 60, 61, 62, 63, 3, 56, 57, 58, + 59, 60, 61, 62, 63, 3, 57, 58, 59, 60, 61, 62, 63, 3, 58, 59, 60, 61, 62, 63, 3, 59, 60, + 61, 62, 63, 3, 60, 61, 62, 63, 3, 61, 62, 63, 3, 62, 63, 3, 63, 3, 3, 5, 6, 7, 9, 10, 11, + 12, 13, 14, 15, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, + 12, 13, 14, 15, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, + 13, 14, 15, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, + 15, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, + 10, 11, 12, 13, 14, 15, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, + 11, 12, 13, 14, 15, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, + 7, 9, 10, 11, 12, 13, 14, 15, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, + 10, 11, 12, 13, 14, 15, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, + 7, 10, 11, 12, 13, 14, 15, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, + 14, 15, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, + 11, 12, 13, 14, 15, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, + 11, 12, 13, 14, 15, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, + 14, 15, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 93, 94, 95, 96, 97, + 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 94, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, + 10, 11, 12, 13, 14, 15, 95, 96, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 96, + 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 97, 98, 99, 100, 3, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 98, 99, 100, 3, 5, 6, 7, 10, 11, 12, 13, 14, 15, 99, 100, 3, 5, 6, 7, 10, + 11, 12, 13, 14, 15, 100, 3, 5, 6, 7, 11, 12, 13, 14, 15, + ]; + let expected = [ + 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 3, 1, 1, 0, + 0, 0, 3, 1, 1, 0, 0, 3, 1, 1, 0, 3, 1, 1, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 3, 0, 3, 3, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 4, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 4, 2, 2, 2, 1, 1, 1, + 1, 1, 1, 0, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 4, 2, 2, 2, 1, 1, 1, 1, 1, + ]; + + let mut i = 0; + + while i < 1825 { + let ai: u64 = a[i]; + let bi: u64 = b[i]; + let expected_val: u64 = expected[i]; + + let result = U128::from(ai).log(U128::from(bi)); + assert_eq(result, U128::from(expected_val)); + i += 1; + } +} \ No newline at end of file From 080117a82f0362776c6987d95814b3a04fa59f49 Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 12:59:57 +0530 Subject: [PATCH 02/12] add set flags to early return --- sway-lib-std/src/math.sw | 1 + 1 file changed, 1 insertion(+) diff --git a/sway-lib-std/src/math.sw b/sway-lib-std/src/math.sw index a52627693ff..2b8e7fa9284 100644 --- a/sway-lib-std/src/math.sw +++ b/sway-lib-std/src/math.sw @@ -343,6 +343,7 @@ impl Logarithm for u256 { // Decimals rounded to 0 if self < base { + set_flags(flags); return 0x00u256; } From e0b364b13246315e7cd91521e618ea48053c779d Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 13:02:38 +0530 Subject: [PATCH 03/12] add flag check to tests --- .../test_programs/u128_inline_tests/src/main.sw | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index bdc5ef5812b..935d6903a9d 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -1,6 +1,6 @@ library; -use std::u128::U128; +use std::{u128::U128, registers::flags}; #[test] fn u128_from_u8() { @@ -688,6 +688,8 @@ fn u128_root() { #[test] fn u128_log() { + let prior_flags = flags(); + let u_128_0: U128 = U128::from((0, 0)); let u_128_1: U128 = U128::from((0, 1)); let u_128_2: U128 = U128::from((0, 2)); @@ -714,6 +716,8 @@ fn u128_log() { assert(u_128_max.log(u_128_9) == u_128_42); assert(u_128_max_div_2.log(u_128_2) == u_128_64); assert(u_128_max_div_2.log(u_128_9) == u_128_21); + + assert(prior_flags == flags()); } #[test] @@ -745,6 +749,8 @@ fn revert_u128_binary_log() { #[test] fn parity_u128_log_with_ruint() { + let prior_flags = flags(); + // Failure cases found by comparing parity with ruint implementation of U128 // https://docs.rs/ruint/latest/src/ruint/log.rs.html#45-89 let a = [ @@ -984,4 +990,6 @@ fn parity_u128_log_with_ruint() { assert_eq(result, U128::from(expected_val)); i += 1; } + + assert(prior_flags == flags()); } \ No newline at end of file From 20879d9bde202e01497b6ec7968ad55cc7799f37 Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 13:09:51 +0530 Subject: [PATCH 04/12] add unsafe math return 0 tests --- sway-lib-std/src/u128.sw | 7 +++++++ .../test_programs/u128_inline_tests/src/main.sw | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index d13147f6980..c92f4b45881 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -742,6 +742,13 @@ impl Logarithm for U128 { assert(base >= 2); // Logarithm is undefined for 0 assert(self != 0); + } else { + // Logarithm is undefined for bases less than 2 + // Logarithm is undefined for 0 + if (base < 2) || (self == 0) { + set_flags(flags); + return 0x00u256; + } } // Decimals rounded to 0 diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index 935d6903a9d..02bfd05ae5a 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -718,6 +718,18 @@ fn u128_log() { assert(u_128_max_div_2.log(u_128_9) == u_128_21); assert(prior_flags == flags()); + + let prior_flags = disable_panic_on_unsafe_math(); + + let zero = U128::from(0_u64); + let one = U128::from(1_u64); + let three = U128::from(3_u64); + + assert(one.log(one) == zero); + assert(zero.log(three) == zero); + + assert(prior_flags == flags()); + set_flags(prior_flags); } #[test] From 171e4f5e1d1ca17eb1d89cfd64c25742a1bad398 Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 13:44:30 +0530 Subject: [PATCH 05/12] add imports, use u128 vals --- sway-lib-std/src/math.sw | 1 - sway-lib-std/src/u128.sw | 13 +++++++------ .../u128_inline_tests/src/main.sw | 18 +++++++++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sway-lib-std/src/math.sw b/sway-lib-std/src/math.sw index 2b8e7fa9284..a52627693ff 100644 --- a/sway-lib-std/src/math.sw +++ b/sway-lib-std/src/math.sw @@ -343,7 +343,6 @@ impl Logarithm for u256 { // Decimals rounded to 0 if self < base { - set_flags(flags); return 0x00u256; } diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index c92f4b45881..6b23a08b9e5 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -739,21 +739,22 @@ impl Logarithm for U128 { // If panic on unsafe math is enabled, only then revert if panic_on_unsafe_math_enabled() { // Logarithm is undefined for bases less than 2 - assert(base >= 2); + assert(base >= U128::from(2_u64)); // Logarithm is undefined for 0 - assert(self != 0); + assert(self != U128::zero()); } else { // Logarithm is undefined for bases less than 2 // Logarithm is undefined for 0 - if (base < 2) || (self == 0) { + if (base < U128::from(2_u64)) || (self == U128::zero()) { set_flags(flags); - return 0x00u256; + return U128::zero(); } } // Decimals rounded to 0 if self < base { - return 0x00u256; + set_flags(flags); + return U128::zero(); } // Estimating the result using change of base formula. Only an estimate because we are doing uint calculations. @@ -774,7 +775,7 @@ impl Logarithm for U128 { // Adjusting the result until the power is less than or equal to self // If pow_res is > than self, then there is an overestimation. If there is an overflow then there is definitely an overestimation. while (pow_res > self) || (of > 0) { - result -= 1; + result -= U128::from(1_u64); // Converting u128 to u32, this cannot fail as the result will be atmost ~128 let parts: (u64, u64) = result.into(); diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index 02bfd05ae5a..6fbcda5c917 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -1,6 +1,6 @@ library; -use std::{u128::U128, registers::flags}; +use std::{u128::U128, registers::flags, flags::{set_flags, disable_panic_on_unsafe_math}}; #[test] fn u128_from_u8() { @@ -698,7 +698,7 @@ fn u128_log() { let u_128_8: U128 = U128::from((0, 8)); let u_128_9: U128 = U128::from((0, 9)); let u_128_10: U128 = U128::from((0, 10)); - let u_128_21: U128 = U128::from((0, 21)); + let u_128_20: U128 = U128::from((0, 20)); let u_128_42: U128 = U128::from((0, 42)); let u_128_64: U128 = U128::from((0, 64)); let u_128_100: U128 = U128::from((0, 100)); @@ -715,7 +715,7 @@ fn u128_log() { assert(u_128_max.log(u_128_2) == u_128_127); assert(u_128_max.log(u_128_9) == u_128_42); assert(u_128_max_div_2.log(u_128_2) == u_128_64); - assert(u_128_max_div_2.log(u_128_9) == u_128_21); + assert(u_128_max_div_2.log(u_128_9) == u_128_20); assert(prior_flags == flags()); @@ -732,6 +732,18 @@ fn u128_log() { set_flags(prior_flags); } +#[test(should_revert)] +fn revert_unsafe_math_u128_1log1() { + let res = U128::from(1_u64).log(U128::from(1_u64)); + log(res); +} + +#[test(should_revert)] +fn revert_unsafe_math_u128_0log_3() { + let res = U128::from(0_u64).log(U128::from(3_u64)); + log(res); +} + #[test] fn u128_binary_log() { let u_128_1: U128 = U128::from((0, 1)); From 0667e1b966c2bef80a32c3d7cd461981a781e635 Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 13:55:09 +0530 Subject: [PATCH 06/12] fix test --- .../test_programs/u128_inline_tests/src/main.sw | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index 6fbcda5c917..b0aa59fe9dd 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -703,7 +703,7 @@ fn u128_log() { let u_128_64: U128 = U128::from((0, 64)); let u_128_100: U128 = U128::from((0, 100)); let u_128_127: U128 = U128::from((0, 127)); - let u_128_max_div_2: U128 = U128::from((1, 0)); + let u64_max_times_two: U128 = U128::from((1, 0)); let u_128_max: U128 = U128::max(); assert(u_128_2.log(u_128_2) == u_128_1); @@ -714,13 +714,15 @@ fn u128_log() { assert(u_128_100.log(u_128_9) == u_128_2); assert(u_128_max.log(u_128_2) == u_128_127); assert(u_128_max.log(u_128_9) == u_128_42); - assert(u_128_max_div_2.log(u_128_2) == u_128_64); - assert(u_128_max_div_2.log(u_128_9) == u_128_20); + assert(u64_max_times_two.log(u_128_2) == u_128_64); + assert(u64_max_times_two.log(u_128_9) == u_128_20); assert(prior_flags == flags()); let prior_flags = disable_panic_on_unsafe_math(); + let before_flags = flags(); + let zero = U128::from(0_u64); let one = U128::from(1_u64); let three = U128::from(3_u64); @@ -728,7 +730,8 @@ fn u128_log() { assert(one.log(one) == zero); assert(zero.log(three) == zero); - assert(prior_flags == flags()); + assert(before_flags == flags()); + set_flags(prior_flags); } From c366d21f59d2305de9e147c087831bbc8a969288 Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 14:09:55 +0530 Subject: [PATCH 07/12] update e2e vm test --- .../should_pass/stdlib/u128_log_test/src/main.sw | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw index 7d9aace3432..aa017641744 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u128_log_test/src/main.sw @@ -12,12 +12,12 @@ fn main() -> bool { let u_128_8: U128 = U128::from((0, 8)); let u_128_9: U128 = U128::from((0, 9)); let u_128_10: U128 = U128::from((0, 10)); - let u_128_21: U128 = U128::from((0, 21)); + let u_128_20: U128 = U128::from((0, 20)); let u_128_42: U128 = U128::from((0, 42)); let u_128_64: U128 = U128::from((0, 64)); let u_128_100: U128 = U128::from((0, 100)); let u_128_127: U128 = U128::from((0, 127)); - let u_128_max_div_2: U128 = U128::from((1, 0)); + let u64_max_times_two: U128 = U128::from((1, 0)); let u_128_max: U128 = U128::max(); @@ -29,8 +29,8 @@ fn main() -> bool { assert(u_128_100.log(u_128_9) == u_128_2); assert(u_128_max.log(u_128_2) == u_128_127); assert(u_128_max.log(u_128_9) == u_128_42); - assert(u_128_max_div_2.log(u_128_2) == u_128_64); - assert(u_128_max_div_2.log(u_128_9) == u_128_21); + assert(u64_max_times_two.log(u_128_2) == u_128_64); + assert(u64_max_times_two.log(u_128_9) == u_128_20); true } From c42c383a63f9c9dca43a864aaf14a3afb86741ab Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 14:49:52 +0530 Subject: [PATCH 08/12] update reverts to depend on flags --- sway-lib-std/src/u128.sw | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 6b23a08b9e5..31929ac8787 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -556,8 +556,11 @@ impl core::ops::Add for U128 { fn add(self, other: Self) -> Self { let mut upper_128 = self.upper.overflowing_add(other.upper); - // If the upper overflows, then the number cannot fit in 128 bits, so panic. - assert(upper_128.upper == 0); + if panic_on_overflow_enabled() { + // If the upper overflows, then the number cannot fit in 128 bits, so panic. + assert(upper_128.upper == 0); + } + let lower_128 = self.lower.overflowing_add(other.lower); // If overflow has occurred in the lower component addition, carry. @@ -566,8 +569,10 @@ impl core::ops::Add for U128 { upper_128 = upper_128.lower.overflowing_add(lower_128.upper); } - // If overflow has occurred in the upper component addition, panic. - assert(upper_128.upper == 0); + if panic_on_overflow_enabled() { + // If overflow has occurred in the upper component addition, panic. + assert(upper_128.upper == 0); + } Self { upper: upper_128.lower, @@ -577,10 +582,13 @@ impl core::ops::Add for U128 { } impl core::ops::Subtract for U128 { - /// Subtract a `U128` from a `U128`. Reverts of overflow. + /// Subtract a `U128` from a `U128`. Reverts on underflow. fn subtract(self, other: Self) -> Self { - // If trying to subtract a larger number, panic. - assert(!(self < other)); + // panic_on_overflow_enabled is also for underflow + if panic_on_overflow_enabled() { + // If trying to subtract a larger number, panic. + assert(!(self < other)); + } let mut upper = self.upper - other.upper; let mut lower = 0; @@ -602,7 +610,9 @@ impl core::ops::Multiply for U128 { // in case both of the `U128` upper parts are bigger than zero, // it automatically means overflow, as any `U128` value // is upper part multiplied by 2 ^ 64 + lower part - assert(self.upper == 0 || other.upper == 0); + if panic_on_unsafe_math_enabled() { + assert(self.upper == 0 || other.upper == 0); + } let mut result = self.lower.overflowing_mul(other.lower); if self.upper == 0 { @@ -622,7 +632,9 @@ impl core::ops::Divide for U128 { fn divide(self, divisor: Self) -> Self { let zero = Self::from((0, 0)); - assert(divisor != zero); + if panic_on_unsafe_math_enabled() { + assert(divisor != zero); + } if self.upper == 0 && divisor.upper == 0 { return Self::from((0, self.lower / divisor.lower)); From f13595c057c490c129b258dbee858a24d5aac9bc Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 16:22:03 +0530 Subject: [PATCH 09/12] add checked muls --- sway-lib-std/src/u128.sw | 58 ++++++++++++++++- .../u128_inline_tests/src/main.sw | 64 ++++++++++++++++++- 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 31929ac8787..1d623e72791 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -12,6 +12,7 @@ use ::flags::{ use ::registers::{flags, overflow}; use ::math::*; use ::result::Result::{self, *}; +use ::option::Option::{self, None, Some}; /// The 128-bit unsigned integer type. /// @@ -663,6 +664,44 @@ impl core::ops::Divide for U128 { } } +fn u64_checked_mul(a: u64, b: u64) -> Option { + let of = asm(a: a, b: b, res) { + mul res a b; + of: u64 + }; + + if of != 0 { + return None; + } + + Some(a * b) +} + +fn u128_checked_mul(a: U128, b: U128) -> Option { + // in case both of the `U128` upper parts are bigger than zero, + // it automatically means overflow, as any `U128` value + // is upper part multiplied by 2 ^ 64 + lower part + if a.upper == 0 || b.upper == 0 { + return None + } + + let mut result = a.lower.overflowing_mul(b.lower); + + if a.upper == 0 { + match u64_checked_mul(a.lower, b.upper) { + None => return None, + Some(v) => { result.upper += v } + } + } else if b.upper == 0 { + match u64_checked_mul(a.upper, b.lower) { + None => return None, + Some(v) => { result.upper += v } + } + } + + Some(result) +} + impl Power for U128 { fn pow(self, exponent: u32) -> Self { let mut value = self; @@ -679,7 +718,10 @@ impl Power for U128 { } while exp & 1 == 0 { - value = value * value; + match u128_checked_mul(value, value) { + None => return U128::zero(), + Some(v) => value = v, + }; exp >>= 1; } @@ -690,9 +732,15 @@ impl Power for U128 { let mut acc = value; while exp > 1 { exp >>= 1; - value = value * value; + match u128_checked_mul(value, value) { + None => return U128::zero(), + Some(v) => value = v, + }; if exp & 1 == 1 { - acc = acc * value; + match u128_checked_mul(acc, value) { + None => return U128::zero(), + Some(v) => acc = v, + }; } } acc @@ -734,6 +782,10 @@ impl BinaryLogarithm for U128 { // If panic on unsafe math is enabled, only then revert if panic_on_unsafe_math_enabled() { assert(self != zero); + } else { + if self == zero { + return zero; + } } if self.upper != 0 { res = Self::from((0, self.upper.log(2) + 64)); diff --git a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw index b0aa59fe9dd..4d7acda31fb 100644 --- a/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/u128_inline_tests/src/main.sw @@ -1,6 +1,6 @@ library; -use std::{u128::U128, registers::flags, flags::{set_flags, disable_panic_on_unsafe_math}}; +use std::{u128::U128, registers::flags, flags::{set_flags, disable_panic_on_unsafe_math, disable_panic_on_overflow}}; #[test] fn u128_from_u8() { @@ -1019,4 +1019,66 @@ fn parity_u128_log_with_ruint() { } assert(prior_flags == flags()); +} + +#[test] +fn u128_overflowing_add() { + let prior_flags = disable_panic_on_overflow(); + let a = U128::max(); + let b = U128::from((0, 1)); + let c = a + b; + + assert(c == U128::from((0, 0))); + + set_flags(prior_flags); +} + +#[test] +fn u128_underflowing_sub() { + let prior_flags = disable_panic_on_overflow(); + let a = U128::from((0, 1)); + let b = U128::from((0, 2)); + let c = a - b; + + assert(c == U128::max()); + + set_flags(prior_flags); +} + +#[test] +fn u128_overflowing_mul() { + let prior_flags = disable_panic_on_overflow(); + let a = U128::max(); + let b = U128::from((0, 2)); + let c = a * b; + + // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + assert(c == U128::from((0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE))); + + set_flags(prior_flags); +} + +#[test] +fn u128_overflowing_pow() { + // Overflow on pow should return 0 if panic is disabled + let prior_flags = disable_panic_on_overflow(); + let a = U128::max(); + + let res = a.pow(2); + + assert(res == U128::from((0, 0))); + + set_flags(prior_flags); +} + +#[test] +fn u128_unsafemath_log2() { + let prior_flags = disable_panic_on_unsafe_math(); + // 0 is not a valid operand for log2 + let a = U128::zero(); + let res = a.log2(); + + assert(res == U128::zero()); + + set_flags(prior_flags); } \ No newline at end of file From f921fb07cede776aad6bbf95aefea9a777f84031 Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 16:46:37 +0530 Subject: [PATCH 10/12] fix pow --- sway-lib-std/src/u128.sw | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 1d623e72791..eea5bd118ea 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -677,25 +677,38 @@ fn u64_checked_mul(a: u64, b: u64) -> Option { Some(a * b) } +fn u64_checked_add(a: u64, b: u64) -> Option { + let of = asm(a: a, b: b, res) { + add res a b; + of: u64 + }; + + if of != 0 { + return None; + } + + Some(a + b) +} + fn u128_checked_mul(a: U128, b: U128) -> Option { // in case both of the `U128` upper parts are bigger than zero, // it automatically means overflow, as any `U128` value // is upper part multiplied by 2 ^ 64 + lower part - if a.upper == 0 || b.upper == 0 { + if a.upper != 0 || b.upper != 0 { return None } let mut result = a.lower.overflowing_mul(b.lower); if a.upper == 0 { - match u64_checked_mul(a.lower, b.upper) { + match u64_checked_add(result.upper, a.lower * b.upper) { None => return None, - Some(v) => { result.upper += v } + Some(v) => { result.upper = v} } } else if b.upper == 0 { - match u64_checked_mul(a.upper, b.lower) { + match u64_checked_add(result.upper, a.upper * b.lower) { None => return None, - Some(v) => { result.upper += v } + Some(v) => { result.upper = v} } } From ba1c226ef471fc9e68c92be61131d1f477c36eee Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 16:50:41 +0530 Subject: [PATCH 11/12] fmt --- sway-lib-std/src/u128.sw | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index eea5bd118ea..0381e6756df 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -703,12 +703,16 @@ fn u128_checked_mul(a: U128, b: U128) -> Option { if a.upper == 0 { match u64_checked_add(result.upper, a.lower * b.upper) { None => return None, - Some(v) => { result.upper = v} + Some(v) => { + result.upper = v + } } } else if b.upper == 0 { match u64_checked_add(result.upper, a.upper * b.lower) { None => return None, - Some(v) => { result.upper = v} + Some(v) => { + result.upper = v + } } } From 1eff119a2afe635b48979bd2295ec18c6d18c75d Mon Sep 17 00:00:00 2001 From: SwayStar123 Date: Wed, 16 Oct 2024 17:00:50 +0530 Subject: [PATCH 12/12] remove unused fn --- sway-lib-std/src/u128.sw | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index 0381e6756df..2018bfb0f84 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -664,19 +664,6 @@ impl core::ops::Divide for U128 { } } -fn u64_checked_mul(a: u64, b: u64) -> Option { - let of = asm(a: a, b: b, res) { - mul res a b; - of: u64 - }; - - if of != 0 { - return None; - } - - Some(a * b) -} - fn u64_checked_add(a: u64, b: u64) -> Option { let of = asm(a: a, b: b, res) { add res a b;