1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

math.big: rework function naming and documentation (#18890)

This commit is contained in:
phoebe 2023-07-20 01:33:07 +02:00 committed by GitHub
parent bd3501affa
commit a49b8f28b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 178 additions and 116 deletions

View File

@ -364,7 +364,7 @@ fn (mut v Element) to_big_integer() big.Integer {
// from_big_integer sets v = n, and returns v. The bit length of n must not exceed 256.
fn (mut v Element) from_big_integer(n big.Integer) !Element {
if n.binary_str().len > 32 * 8 {
if n.bin_str().len > 32 * 8 {
return error('invalid edwards25519 element input size')
}
mut bytes, _ := n.bytes()

View File

@ -119,7 +119,7 @@ fn test_scalar_set_uniform_bytes() {
// mod, _ := new(big.Integer).SetString("27742317777372353535851937790883648493", 10)
mut mod := big.integer_from_string('27742317777372353535851937790883648493')!
// mod.Add(mod, new(big.Integer).Lsh(big.NewInt(1), 252))
mod = mod + big.integer_from_i64(1).lshift(252)
mod = mod + big.integer_from_i64(1).left_shift(252)
mut sc := generate_scalar(100)!
inp := rand.bytes(64)!

View File

@ -88,7 +88,7 @@ pub fn (a &Number) % (b &Number) Number {
return c
}*/
pub fn divmod(a &Number, b &Number) (Number, Number) {
pub fn div_mod(a &Number, b &Number) (Number, Number) {
c := Number{}
d := Number{}
#c.value = a.val.value / b.val.value
@ -97,6 +97,11 @@ pub fn divmod(a &Number, b &Number) (Number, Number) {
return c, d
}
[deprecated: 'use div_mod(a, b) instead']
pub fn divmod(a &Number, b &Number) (Number, Number) {
return div_mod(a, b)
}
pub fn cmp(a &Number, b &Number) int {
res := 0
@ -137,37 +142,62 @@ pub fn (a &Number) isqrt() Number {
return b
}
[deprecated: 'use bitwise_and(a, b) instead']
pub fn b_and(a &Number, b &Number) Number {
return bitwise_and(a, b)
}
[deprecated: 'use bitwise_or(a, b) instead']
pub fn b_or(a &Number, b &Number) Number {
return bitwise_or(a, b)
}
[deprecated: 'use bitwise_xor(a, b) instead']
pub fn b_xor(a &Number, b &Number) Number {
return bitwise_xor(a, b)
}
pub fn bitwise_and(a &Number, b &Number) Number {
c := Number{}
#c.value = a.val.value & b.val.value
return c
}
pub fn b_or(a &Number, b &Number) Number {
pub fn bitwise_or(a &Number, b &Number) Number {
c := Number{}
#c.value = a.val.value | b.val.value
return c
}
pub fn b_xor(a &Number, b &Number) Number {
pub fn bitwise_xor(a &Number, b &Number) Number {
c := Number{}
#c.value = a.val.value ^ b.val.value
return c
}
pub fn (a &Number) lshift(nbits int) Number {
[deprecated: 'use a.left_shift(amount) instead']
pub fn (a &Number) lshift(amount int) Number {
return a.left_shift(amount)
}
[deprecated: 'use a.right_shift(amount) instead']
pub fn (a &Number) rshift(amount int) Number {
return a.right_shift(amount)
}
pub fn (a &Number) left_shift(amount int) Number {
c := Number{}
#c.value = a.val.value << BigInt(+nbits)
#c.value = a.val.value << BigInt(+amount)
return c
}
pub fn (a &Number) rshift(nbits int) Number {
pub fn (a &Number) right_shift(amount int) Number {
c := Number{}
#c.value = a.val.value << BigInt(+nbits)
#c.value = a.val.value << BigInt(+amount)
return c
}
@ -193,6 +223,11 @@ pub fn factorial(nn &Number) Number {
return a
}
[deprecated: 'use factorial_int instead']
pub fn fact(n int) Number {
return factorial_int(n)
}
pub fn factorial_int(n int) Number {
return factorial(from_int(n))
}

View File

@ -389,7 +389,7 @@ const factorial_test_data = [
]
// vfmt on
// for lshift and rshift
// for left_shift and right_shift
struct ShiftTest {
base TestInteger
amount u32
@ -397,7 +397,7 @@ struct ShiftTest {
}
// vfmt off
const lshift_test_data = [
const left_shift_test_data = [
ShiftTest{ 45, 2, 45 * 4 },
ShiftTest{ 45, 3, 45 * 8 },
ShiftTest{ 45, 4, 45 * 16 },
@ -406,7 +406,7 @@ const lshift_test_data = [
ShiftTest{ [u8(1), 1, 1], 56, [u8(1), 1, 1, 0, 0, 0, 0, 0, 0, 0] },
]
const rshift_test_data = [
const right_shift_test_data = [
ShiftTest{ 45, 3, 5 },
ShiftTest{ 0x13374956, 16, 0x1337 },
ShiftTest{ [u8(1), 1, 1, 0, 0, 0, 0, 0, 0, 0], 56, [u8(1), 1, 1] },
@ -435,7 +435,7 @@ const bit_len_test_data = [
BitLenTest{ big.zero_int, 0 },
BitLenTest{ big.one_int, 1 },
BitLenTest{ u32(0xffffffff), 32 },
BitLenTest{ big.one_int.lshift(1239), 1240 },
BitLenTest{ big.one_int.left_shift(1239), 1240 },
BitLenTest{ '4338476092346017364013796407961305761039463198075691378460917856', 212 },
]
// vfmt on
@ -639,15 +639,15 @@ fn test_inc_and_dec() {
assert b == c
}
fn test_lshift() {
for t in lshift_test_data {
assert t.base.parse().lshift(t.amount) == t.expected.parse()
fn test_left_shift() {
for t in left_shift_test_data {
assert t.base.parse().left_shift(t.amount) == t.expected.parse()
}
}
fn test_rshift() {
for t in rshift_test_data {
assert t.base.parse().rshift(t.amount) == t.expected.parse()
fn test_right_shift() {
for t in right_shift_test_data {
assert t.base.parse().right_shift(t.amount) == t.expected.parse()
}
}
@ -693,7 +693,7 @@ fn test_isqrt() {
}
fn test_bitwise_ops() {
a := big.integer_from_int(1).lshift(512)
a := big.integer_from_int(1).left_shift(512)
b := a - big.one_int
assert a.bitwise_and(b) == big.zero_int
assert b.bitwise_xor(b) == big.zero_int
@ -732,7 +732,7 @@ fn test_set_bit() {
a.set_bit(3, true)
assert a.int() == 40
a.set_bit(50, true)
assert a == big.one_int.lshift(50) + big.integer_from_int(40)
assert a == big.one_int.left_shift(50) + big.integer_from_int(40)
b := a
a.set_bit(100, false)
assert a == b

View File

@ -34,9 +34,9 @@ fn binary_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient [
// align
if lead_zer_remainder < lead_zer_divisor {
lshift_in_place(mut divisor, lead_zer_divisor - lead_zer_remainder)
left_shift_in_place(mut divisor, lead_zer_divisor - lead_zer_remainder)
} else if lead_zer_remainder > lead_zer_divisor {
lshift_in_place(mut remainder, lead_zer_remainder - lead_zer_divisor)
left_shift_in_place(mut remainder, lead_zer_remainder - lead_zer_divisor)
}
$if debug {
@ -47,13 +47,13 @@ fn binary_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient [
bit_set(mut quotient, bit_idx)
subtract_align_last_byte_in_place(mut remainder, divisor)
}
rshift_in_place(mut divisor, 1)
right_shift_in_place(mut divisor, 1)
}
// adjust
if lead_zer_remainder > lead_zer_divisor {
// rshift_in_place(mut quotient, lead_zer_remainder - lead_zer_divisor)
rshift_in_place(mut remainder, lead_zer_remainder - lead_zer_divisor)
// right_shift_in_place(mut quotient, lead_zer_remainder - lead_zer_divisor)
right_shift_in_place(mut remainder, lead_zer_remainder - lead_zer_divisor)
}
shrink_tail_zeros(mut remainder)
shrink_tail_zeros(mut quotient)
@ -115,7 +115,7 @@ fn subtract_align_last_byte_in_place(mut a []u32, b []u32) {
// there is no overflow. We know that the last bits are zero
// and that n <= 32
[direct_array_access; inline]
fn lshift_in_place(mut a []u32, n u32) {
fn left_shift_in_place(mut a []u32, n u32) {
mut carry := u32(0)
mut prec_carry := u32(0)
mask := ((u32(1) << n) - 1) << (32 - n)
@ -130,7 +130,7 @@ fn lshift_in_place(mut a []u32, n u32) {
// logical right shift without control because these digits have already been
// shift left before
[direct_array_access; inline]
fn rshift_in_place(mut a []u32, n u32) {
fn right_shift_in_place(mut a []u32, n u32) {
mut carry := u32(0)
mut prec_carry := u32(0)
mask := u32((1 << n) - 1)

View File

@ -2,35 +2,35 @@ module big
import rand
fn test_lshift_in_place() {
fn test_left_shift_in_place() {
mut a := [u32(1), 1, 1, 1, 1]
lshift_in_place(mut a, 1)
left_shift_in_place(mut a, 1)
assert a == [u32(2), 2, 2, 2, 2]
lshift_in_place(mut a, 7)
left_shift_in_place(mut a, 7)
assert a == [u32(256), 256, 256, 256, 256]
mut b := [u32(0x80000001), 0xc0000000, 0x80000000, 0x7fffffff]
lshift_in_place(mut b, 1)
left_shift_in_place(mut b, 1)
assert b == [u32(2), 0x80000001, 1, 0xffffffff]
mut c := [u32(0x00ffffff), 0xf0f0f0f0, 1, 0x3fffffff, 1]
lshift_in_place(mut c, 2)
left_shift_in_place(mut c, 2)
assert c == [u32(0x3fffffc), 0xc3c3c3c0, 7, 0xfffffffc, 4]
}
fn test_rshift_in_place() {
fn test_right_shift_in_place() {
mut a := [u32(2), 2, 2, 2, 2]
rshift_in_place(mut a, 1)
right_shift_in_place(mut a, 1)
assert a == [u32(1), 1, 1, 1, 1]
a = [u32(256), 256, 256, 256, 256]
rshift_in_place(mut a, 7)
right_shift_in_place(mut a, 7)
assert a == [u32(2), 2, 2, 2, 2]
a = [u32(0), 0, 1]
rshift_in_place(mut a, 1)
right_shift_in_place(mut a, 1)
assert a == [u32(0), 0x80000000, 0]
mut b := [u32(3), 0x80000001, 1, 0xffffffff]
rshift_in_place(mut b, 1)
right_shift_in_place(mut b, 1)
assert b == [u32(0x80000001), 0xc0000000, 0x80000000, 0x7fffffff]
mut c := [u32(0x03ffffff), 0xc3c3c3c0, 7, 0xfffffffc, 4]
rshift_in_place(mut c, 2)
right_shift_in_place(mut c, 2)
assert c == [u32(0x00ffffff), 0xf0f0f0f0, 1, 0x3fffffff, 1]
}

View File

@ -29,8 +29,8 @@ fn (m Integer) montgomery() MontgomeryContext {
// ri := multiplicative inverse of r in the ring Z/nZ
// ri * r == 1 (mod n)
// ni = ((ri * 2^(log_2(n))) - 1) / n
ni: (one_int.lshift(b).mod_inv(n).lshift(b) - one_int) / n
rr: one_int.lshift(b * 2) % n
ni: (one_int.left_shift(b).mod_inv(n).left_shift(b) - one_int) / n
rr: one_int.left_shift(b * 2) % n
}
}
@ -164,7 +164,7 @@ fn (a Integer) mont_even(x Integer, m Integer) Integer {
}
m1, j := m.rsh_to_set_bit()
m2 := one_int.lshift(j)
m2 := one_int.left_shift(j)
$if debug {
assert m1 * m2 == m
@ -321,7 +321,7 @@ fn (a Integer) to_mont(ctx MontgomeryContext) Integer {
fn (a Integer) from_mont(ctx MontgomeryContext) Integer {
log2n := u32(ctx.n.bit_len())
r := (a + ((a.mask_bits(log2n) * ctx.ni).mask_bits(log2n) * ctx.n)).rshift(log2n)
r := (a + ((a.mask_bits(log2n) * ctx.ni).mask_bits(log2n) * ctx.n)).right_shift(log2n)
return if r.abs_cmp(ctx.n) >= 0 {
r - ctx.n

View File

@ -265,59 +265,61 @@ fn integer_from_regular_string(characters string, radix u32) Integer {
}
}
// abs returns the absolute value of the integer.
pub fn (integer Integer) abs() Integer {
return if integer.signum == 0 {
// abs returns the absolute value of the integer `a`.
pub fn (a Integer) abs() Integer {
return if a.signum == 0 {
zero_int
} else {
Integer{
digits: integer.digits.clone()
digits: a.digits.clone()
signum: 1
}
}
}
// neg returns the result of negation of the integer.
pub fn (integer Integer) neg() Integer {
return if integer.signum == 0 {
// neg returns the result of negation of the integer `a`.
pub fn (a Integer) neg() Integer {
return if a.signum == 0 {
zero_int
} else {
Integer{
digits: integer.digits.clone()
signum: -integer.signum
digits: a.digits.clone()
signum: -a.signum
}
}
}
pub fn (integer Integer) + (addend Integer) Integer {
// + returns the sum of the integers `augend` and `addend`.
pub fn (augend Integer) + (addend Integer) Integer {
// Quick exits
if integer.signum == 0 {
if augend.signum == 0 {
return addend.clone()
}
if addend.signum == 0 {
return integer.clone()
return augend.clone()
}
// Non-zero cases
return if integer.signum == addend.signum {
integer.add(addend)
return if augend.signum == addend.signum {
augend.add(addend)
} else { // Unequal signs
integer.subtract(addend)
augend.subtract(addend)
}
}
pub fn (integer Integer) - (subtrahend Integer) Integer {
// - returns the difference of the integers `minuend` and `subtrahend`
pub fn (minuend Integer) - (subtrahend Integer) Integer {
// Quick exits
if integer.signum == 0 {
if minuend.signum == 0 {
return subtrahend.neg()
}
if subtrahend.signum == 0 {
return integer.clone()
return minuend.clone()
}
// Non-zero cases
return if integer.signum == subtrahend.signum {
integer.subtract(subtrahend)
return if minuend.signum == subtrahend.signum {
minuend.subtract(subtrahend)
} else {
integer.add(subtrahend)
minuend.add(subtrahend)
}
}
@ -346,44 +348,45 @@ fn (integer Integer) subtract(subtrahend Integer) Integer {
}
}
pub fn (integer Integer) * (multiplicand Integer) Integer {
// * returns the product of the integers `multiplicand` and `multiplier`.
pub fn (multiplicand Integer) * (multiplier Integer) Integer {
// Quick exits
if integer.signum == 0 || multiplicand.signum == 0 {
if multiplicand.signum == 0 || multiplier.signum == 0 {
return zero_int
}
if integer == one_int {
if multiplicand == one_int {
return multiplier.clone()
}
if multiplier == one_int {
return multiplicand.clone()
}
if multiplicand == one_int {
return integer.clone()
}
// The final sign is the product of the signs
mut storage := []u32{len: integer.digits.len + multiplicand.digits.len}
multiply_digit_array(integer.digits, multiplicand.digits, mut storage)
mut storage := []u32{len: multiplicand.digits.len + multiplier.digits.len}
multiply_digit_array(multiplicand.digits, multiplier.digits, mut storage)
return Integer{
signum: integer.signum * multiplicand.signum
signum: multiplicand.signum * multiplier.signum
digits: storage
}
}
// div_mod returns the quotient and remainder of the integer division.
pub fn (integer Integer) div_mod(divisor Integer) (Integer, Integer) {
// div_mod returns the quotient and remainder from the division of the integers `dividend` divided by `divisor`.
pub fn (dividend Integer) div_mod(divisor Integer) (Integer, Integer) {
// Quick exits
if divisor.signum == 0 {
panic('Cannot divide by zero')
}
if integer.signum == 0 {
if dividend.signum == 0 {
return zero_int, zero_int
}
if divisor == one_int {
return integer.clone(), zero_int
return dividend.clone(), zero_int
}
if divisor.signum == -1 {
q, r := integer.div_mod(divisor.neg())
q, r := dividend.div_mod(divisor.neg())
return q.neg(), r
}
if integer.signum == -1 {
q, r := integer.neg().div_mod(divisor)
if dividend.signum == -1 {
q, r := dividend.neg().div_mod(divisor)
if r.signum == 0 {
return q.neg(), zero_int
} else {
@ -391,9 +394,9 @@ pub fn (integer Integer) div_mod(divisor Integer) (Integer, Integer) {
}
}
// Division for positive integers
mut q := []u32{cap: integer.digits.len - divisor.digits.len + 1}
mut r := []u32{cap: integer.digits.len}
divide_digit_array(integer.digits, divisor.digits, mut q, mut r)
mut q := []u32{cap: dividend.digits.len - divisor.digits.len + 1}
mut r := []u32{cap: dividend.digits.len}
divide_digit_array(dividend.digits, divisor.digits, mut q, mut r)
quotient := Integer{
signum: if q.len == 0 { 0 } else { 1 }
digits: q
@ -405,13 +408,15 @@ pub fn (integer Integer) div_mod(divisor Integer) (Integer, Integer) {
return quotient, remainder
}
pub fn (a Integer) / (b Integer) Integer {
q, _ := a.div_mod(b)
// / returns the quotient of `dividend` divided by `divisor`.
pub fn (dividend Integer) / (divisor Integer) Integer {
q, _ := dividend.div_mod(divisor)
return q
}
pub fn (a Integer) % (b Integer) Integer {
_, r := a.div_mod(b)
// % returns the remainder of `dividend` divided by `divisor`.
pub fn (dividend Integer) % (divisor Integer) Integer {
_, r := dividend.div_mod(divisor)
return r
}
@ -454,7 +459,7 @@ fn (a Integer) mask_bits(n u32) Integer {
}
}
// pow returns the integer `a` raised to the power of the u32 `exponent`.
// pow returns the integer `base` raised to the power of the u32 `exponent`.
pub fn (base Integer) pow(exponent u32) Integer {
if exponent == 0 {
return one_int
@ -475,7 +480,7 @@ pub fn (base Integer) pow(exponent u32) Integer {
return x * y
}
// mod_pow returns the integer `a` raised to the power of the u32 `exponent` modulo the integer `modulus`.
// mod_pow returns the integer `base` raised to the power of the u32 `exponent` modulo the integer `modulus`.
pub fn (base Integer) mod_pow(exponent u32, modulus Integer) Integer {
if exponent == 0 {
return one_int
@ -545,16 +550,17 @@ pub fn (base Integer) big_mod_pow(exponent Integer, modulus Integer) !Integer {
}
}
// inc returns the integer `a` incremented by 1.
// inc increments `a` by 1 in place.
pub fn (mut a Integer) inc() {
a = a + one_int
}
// dec returns the integer `a` decremented by 1.
// dec decrements `a` by 1 in place.
pub fn (mut a Integer) dec() {
a = a - one_int
}
// == returns `true` if the integers `a` and `b` are equal in value and sign.
pub fn (a Integer) == (b Integer) bool {
return a.signum == b.signum && a.digits.len == b.digits.len && a.digits == b.digits
}
@ -565,6 +571,7 @@ pub fn (a Integer) abs_cmp(b Integer) int {
return compare_digit_array(a.digits, b.digits)
}
// < returns `true` if the integer `a` is less than `b`.
pub fn (a Integer) < (b Integer) bool {
// Quick exits based on signum value:
if a.signum < b.signum {
@ -609,7 +616,7 @@ pub fn (mut a Integer) set_bit(i u32, value bool) {
if target_index >= a.digits.len {
if value {
a = one_int.lshift(i).bitwise_or(a)
a = one_int.left_shift(i).bitwise_or(a)
}
return
}
@ -676,8 +683,14 @@ pub fn (a Integer) bitwise_xor(b Integer) Integer {
}
// lshift returns the integer `a` shifted left by `amount` bits.
[direct_array_access]
[deprecated: 'use a.Integer.left_shift(amount) instead']
pub fn (a Integer) lshift(amount u32) Integer {
return a.left_shift(amount)
}
// left_shift returns the integer `a` shifted left by `amount` bits.
[direct_array_access]
pub fn (a Integer) left_shift(amount u32) Integer {
if a.signum == 0 {
return a
}
@ -700,8 +713,14 @@ pub fn (a Integer) lshift(amount u32) Integer {
}
// rshift returns the integer `a` shifted right by `amount` bits.
[direct_array_access]
[deprecated: 'use a.Integer.right_shift(amount) instead']
pub fn (a Integer) rshift(amount u32) Integer {
return a.right_shift(amount)
}
// right_shift returns the integer `a` shifted right by `amount` bits.
[direct_array_access]
pub fn (a Integer) right_shift(amount u32) Integer {
if a.signum == 0 {
return a
}
@ -727,8 +746,14 @@ pub fn (a Integer) rshift(amount u32) Integer {
}
// binary_str returns the binary string representation of the integer `a`.
[direct_array_access]
[deprecated: 'use integer.bin_str() instead']
pub fn (integer Integer) binary_str() string {
return integer.bin_str()
}
// bin_str returns the binary string representation of the integer `a`.
[direct_array_access]
pub fn (integer Integer) bin_str() string {
// We have the zero integer
if integer.signum == 0 {
return '0'
@ -919,9 +944,9 @@ pub fn (a Integer) isqrt() Integer {
}
mut result := zero_int
for shift >= 0 {
result = result.lshift(1)
result = result.left_shift(1)
larger := result + one_int
if (larger * larger).abs_cmp(a.rshift(u32(shift))) <= 0 {
if (larger * larger).abs_cmp(a.right_shift(u32(shift))) <= 0 {
result = larger
}
shift -= 2
@ -968,7 +993,7 @@ fn gcd_binary(x Integer, y Integer) Integer {
a, _ = diff.abs().rsh_to_set_bit()
}
return b.lshift(shift)
return b.left_shift(shift)
}
// mod_inverse calculates the multiplicative inverse of the integer `a` in the ring `/n`.
@ -1026,7 +1051,7 @@ fn (a Integer) mod_inv(m Integer) Integer {
tmp := if q == one_int {
x
} else if q.digits.len == 1 && q.digits[0] & (q.digits[0] - 1) == 0 {
x.lshift(u32(bits.trailing_zeros_32(q.digits[0])))
x.left_shift(u32(bits.trailing_zeros_32(q.digits[0])))
} else {
q * x
} + y
@ -1065,7 +1090,7 @@ fn (x Integer) rsh_to_set_bit() (Integer, u32) {
n++
}
n = (n << 5) + u32(bits.trailing_zeros_32(x.digits[n]))
return x.rshift(n), n
return x.right_shift(n), n
}
[direct_array_access; inline]

View File

@ -27,11 +27,11 @@ fn newton_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient [
digits: operand_b
}
k := bit_length(a) + bit_length(b) // a*b < 2**k
k := a.bit_len() + b.bit_len() // a*b < 2**k
mut x := integer_from_int(2) // 0 < x < 2**(k+1)/b // initial guess for convergence
// https://en.wikipedia.org/wiki/Division_algorithm#Newton%E2%80%93Raphson_division
// use 48/17 - 32/17.D (divisor)
initial_guess := (((integer_from_int(48) - (integer_from_int(32) * b)) * integer_from_i64(0x0f0f0f0f0f0f0f0f)).rshift(64)).neg() // / 17 == 0x11
initial_guess := (((integer_from_int(48) - (integer_from_int(32) * b)) * integer_from_i64(0x0f0f0f0f0f0f0f0f)).right_shift(64)).neg() // / 17 == 0x11
if initial_guess > zero_int {
x = initial_guess
}
@ -39,12 +39,12 @@ fn newton_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient [
pow2_k_plus_1 := pow2(k + 1) // outside of the loop to optimize allocatio
for lastx != x { // main loop
lastx = x
x = (x * (pow2_k_plus_1 - (x * b))).rshift(u32(k))
x = (x * (pow2_k_plus_1 - (x * b))).right_shift(u32(k))
}
if x * b < pow2(k) {
x.inc()
}
mut q := (a * x).rshift(u32(k))
mut q := (a * x).right_shift(u32(k))
// possible adjustments. see literature
if q * b > a {
q.dec()
@ -61,6 +61,7 @@ fn newton_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient [
}
// bit_length returns the number of bits needed to represent the absolute value of the integer a.
[deprecated: 'use a.bit_len() instead']
[inline]
pub fn bit_length(a Integer) int {
return a.digits.len * 32 - bits.leading_zeros_32(a.digits.last())
@ -141,9 +142,9 @@ fn karatsuba_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage
subtract_in_place(mut p_2, storage) // p_1
subtract_in_place(mut p_2, p_3)
// return p_1.lshift(2 * u32(half * 32)) + p_2.lshift(u32(half * 32)) + p_3
lshift_digits_in_place(mut storage, 2 * half)
lshift_digits_in_place(mut p_2, half)
// return p_1.left_shift(2 * u32(half * 32)) + p_2.left_shift(u32(half * 32)) + p_3
left_shift_digits_in_place(mut storage, 2 * half)
left_shift_digits_in_place(mut p_2, half)
add_in_place(mut storage, p_2)
add_in_place(mut storage, p_3)
@ -224,21 +225,22 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3
ptemp += a1
qtemp += b1
p1 := ptemp * qtemp
p2 := ((ptemp + a2).lshift(1) - a0) * ((qtemp + b2).lshift(1) - b0)
p2 := ((ptemp + a2).left_shift(1) - a0) * ((qtemp + b2).left_shift(1) - b0)
pinf := a2 * b2
mut t2 := (p2 - vm1) / three_int
mut tm1 := (p1 - vm1).rshift(1)
mut tm1 := (p1 - vm1).right_shift(1)
mut t1 := p1 - p0
t2 = (t2 - t1).rshift(1)
t2 = (t2 - t1).right_shift(1)
t1 = (t1 - tm1 - pinf)
t2 = t2 - pinf.lshift(1)
t2 = t2 - pinf.left_shift(1)
tm1 = tm1 - t2
// shift amount
s := u32(k) << 5
result := (((pinf.lshift(s) + t2).lshift(s) + t1).lshift(s) + tm1).lshift(s) + p0
result := (((pinf.left_shift(s) + t2).left_shift(s) + t1).left_shift(s) + tm1).left_shift(s) +
p0
storage = result.digits.clone()
}
@ -255,7 +257,7 @@ fn pow2(k int) Integer {
// optimized left shift in place. amount must be positive
[direct_array_access]
fn lshift_digits_in_place(mut a []u32, amount int) {
fn left_shift_digits_in_place(mut a []u32, amount int) {
a_len := a.len
// control or allocate capacity
for _ in a_len .. a_len + amount {
@ -271,7 +273,7 @@ fn lshift_digits_in_place(mut a []u32, amount int) {
// optimized right shift in place. amount must be positive
[direct_array_access]
fn rshift_digits_in_place(mut a []u32, amount int) {
fn right_shift_digits_in_place(mut a []u32, amount int) {
for index := 0; index < a.len - amount; index++ {
a[index] = a[index + amount]
}

View File

@ -24,9 +24,9 @@ fn test_add_in_place() {
assert a == [u32(0x17ff72ad), 0x1439]
}
fn test_lshift_digits_in_place() {
fn test_left_shift_digits_in_place() {
mut a := [u32(5), 6, 7, 8]
lshift_digits_in_place(mut a, 2)
left_shift_digits_in_place(mut a, 2)
assert a == [u32(0), 0, 5, 6, 7, 8]
}