Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

math.big: add isqrt_checked and standardize error format #18939

Merged
merged 3 commits into from
Jul 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion vlib/math/big/division_array_ops_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,6 @@ fn random_number(length int) Integer {
nr := numbers[i]
stri = stri + nr.ascii_str()
}
res := integer_from_string(stri) or { panic('error in random_number') }
res := integer_from_string(stri) or { panic(err) }
return res
}
19 changes: 14 additions & 5 deletions vlib/math/big/integer.v
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pub fn integer_from_string(characters string) !Integer {
// integer_from_radix creates a new `big.Integer` from the given string and radix.
pub fn integer_from_radix(all_characters string, radix u32) !Integer {
if radix < 2 || radix > 36 {
return error('Radix must be between 2 and 36 (inclusive)')
return error('math.big: Radix must be between 2 and 36 (inclusive)')
}
characters := all_characters.to_lower()
validate_string(characters, radix)!
Expand Down Expand Up @@ -186,10 +186,10 @@ fn validate_string(characters string, radix u32) ! {
value := big.digit_array.index(digit)

if value == -1 {
return error('Invalid character ${digit}')
return error('math.big: Invalid character ${digit}')
}
if value >= radix {
return error('Invalid character ${digit} for base ${radix}')
return error('math.big: Invalid character ${digit} for base ${radix}')
}
}
}
Expand Down Expand Up @@ -972,10 +972,19 @@ pub fn (a Integer) factorial() Integer {
return product
}

// isqrt returns the closest integer square root of the given integer.
// isqrt returns the closest integer square root of the integer `a`.
//
// WARNING: this method will panic if `a < 0`. Refer to isqrt_checked for a safer version.
[inline]
pub fn (a Integer) isqrt() Integer {
return a.isqrt_checked() or { panic(err) }
}

// isqrt returns the closest integer square root of the integer `a`.
// An error is returned if `a < 0`.
pub fn (a Integer) isqrt_checked() !Integer {
if a.signum < 0 {
panic('Cannot obtain square root of negative integer')
return error('math.big: Cannot calculate square root of negative integer')
}
if a.signum == 0 {
return a
Expand Down
16 changes: 8 additions & 8 deletions vlib/math/big/special_array_ops_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,25 @@ fn test_multiply_karatsuba_01() {
karatsuba_multiply_digit_array(a, b, mut c)
assert c == [u32(0xcaf2722e), 0x55eb2c5a, 0x3dc]

a_operand := integer_from_string('95484736384949495947362') or { panic('error') }
b_operand := integer_from_string('39474638493') or { panic('error') }
a_operand := integer_from_string('95484736384949495947362') or { panic(err) }
b_operand := integer_from_string('39474638493') or { panic(err) }
Comment on lines +70 to +71
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inside test functions, you can just use ! instead of or { panic(err) }

c = []u32{len: a_operand.digits.len + b_operand.digits.len, init: 0}
karatsuba_multiply_digit_array(a_operand.digits, b_operand.digits, mut c)
expected := integer_from_string('3769225450395285038584683507005466') or { panic('error') }
expected := integer_from_string('3769225450395285038584683507005466') or { panic(err) }
assert c == expected.digits
}

fn test_multiply_karatsuba_02() {
a := integer_from_string('53575430359313366047421252453000090528070240585276680372187519418517552556246806124659918940784792906379733645877657341259357264284615702179922887873492874019672838874121154927105373025311855709389770910765') or {
panic('error')
panic(err)
}
b := integer_from_string('977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688531898668229388286706296786321423078510899614439367') or {
panic('error')
panic(err)
}
mut c := []u32{len: a.digits.len + b.digits.len + 1, init: 0}
karatsuba_multiply_digit_array(a.digits, b.digits, mut c)
expected := integer_from_string('52348074924977237255285644820010078601114587486470740900886892189662650320988400136613780986308710610258879824881256666730655821800564143426560480113864123642197317383052431412305975584645367703594190956925565749714310612399025459615546540332117815550470167143256687163102859337019449165214274088466835988832405507818643018779158891710706073875995722420460085755') or {
panic('error')
panic(err)
}
}

Expand Down Expand Up @@ -135,10 +135,10 @@ fn test_newton_divide_06() {

fn test_newton_divide_07() {
a := integer_from_string('52348074924977237255285644820010078601114587486470740900886892189662650320988400136613780986308710610258879824881256666730655821800564143426560480113864123642197317383052431412305975584645367703594190956925565749714310612399025459615546540332117815550470167143256687163102859337019449165214274088466835988832405507818643018779158891710706073875995722420460085757') or {
panic('error')
panic(err)
}
b := integer_from_string('977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688531898668229388286706296786321423078510899614439367') or {
panic('error')
panic(err)
}
mut q := []u32{cap: a.digits.len - b.digits.len + 1}
mut r := []u32{cap: a.digits.len}
Expand Down