Skip to content

Commit

Permalink
examples: add pidigits.v; optimise math.big's Integer divide a bit (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
spytheman committed Apr 9, 2024
1 parent d25e349 commit 4dcc926
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 14 deletions.
52 changes: 52 additions & 0 deletions examples/pidigits.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module main

import os
import math.big

const digits_to_print = os.args[1] or { '1000' }.int()

const zero = big.integer_from_int(0)
const one = big.integer_from_int(1)
const two = big.integer_from_int(2)
const three = big.integer_from_int(3)
const four = big.integer_from_int(4)
const ten = big.integer_from_int(10)

fn main() {
unbuffer_stdout()
mut digits_printed := 0
mut k := one
mut n1 := four
mut n2 := three
mut d := one
mut u := zero
mut v := zero
mut w := zero
for {
u = n1 / d
v = n2 / d
u_int := u.int()
v_int := v.int()
if u_int == v_int {
print(u_int)
digits_printed++
if digits_printed >= digits_to_print {
println('')
return
}
to_minus := u * ten * d
n1 = n1 * ten - to_minus
n2 = n2 * ten - to_minus
} else {
k2 := k * two
u = n1 * (k2 - one)
v = n2 * two
w = n1 * (k - one)
n1 = u + v
u = n2 * (k + two)
n2 = w + u
d = d * (k2 + one)
k += one
}
}
}
4 changes: 1 addition & 3 deletions vlib/math/big/array_ops.v
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,7 @@ fn divide_digit_array(operand_a []u32, operand_b []u32, mut quotient []u32, mut
// a < b => q, r = 0, a
if cmp_result < 0 {
quotient.clear()
for index in 0 .. operand_a.len {
remainder << operand_a[index]
}
remainder << operand_a
return
}
if operand_b.len == 1 {
Expand Down
8 changes: 2 additions & 6 deletions vlib/math/big/division_array_ops.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import math.bits
// Both quotient and remaider are allocated but of length 0
@[direct_array_access]
fn binary_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient []u32, mut remainder []u32) {
for index in 0 .. operand_a.len {
remainder << operand_a[index]
}
remainder << operand_a

len_diff := operand_a.len - operand_b.len
$if debug {
Expand All @@ -20,9 +18,7 @@ fn binary_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient [
for _ in 0 .. len_diff {
divisor << u32(0)
}
for index in 0 .. operand_b.len {
divisor << operand_b[index]
}
divisor << operand_b
for _ in 0 .. len_diff + 1 {
quotient << u32(0)
}
Expand Down
3 changes: 3 additions & 0 deletions vlib/math/big/integer.v
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,14 @@ pub fn (mut a Integer) dec() {
}

// == returns `true` if the integers `a` and `b` are equal in value and sign.
@[inline]
pub fn (a Integer) == (b Integer) bool {
return a.signum == b.signum && a.digits.len == b.digits.len && a.digits == b.digits
}

// abs_cmp returns the result of comparing the magnitudes of the integers `a` and `b`.
// It returns a negative int if `|a| < |b|`, 0 if `|a| == |b|`, and a positive int if `|a| > |b|`.
@[inline]
pub fn (a Integer) abs_cmp(b Integer) int {
return compare_digit_array(a.digits, b.digits)
}
Expand Down Expand Up @@ -921,6 +923,7 @@ fn u32_to_hex_with_lz(value u32) string {

// int returns the integer value of the integer `a`.
// NOTE: This may cause loss of precision.
@[direct_array_access]
pub fn (a Integer) int() int {
if a.signum == 0 {
return 0
Expand Down
10 changes: 5 additions & 5 deletions vlib/math/big/special_array_ops.v
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ fn karatsuba_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage

// thanks to the base cases we can pass zero-length arrays to the mult func
half := imax(operand_a.len, operand_b.len) / 2
a_l := operand_a[0..half]
a_h := operand_a[half..]
a_l := unsafe { operand_a[0..half] }
a_h := unsafe { operand_a[half..] }
mut b_l := []u32{}
mut b_h := []u32{}
if half <= operand_b.len {
Expand Down Expand Up @@ -169,15 +169,15 @@ fn toom3_multiply_digit_array(operand_a []u32, operand_b []u32, mut storage []u3

// Slices of a and b
a0 := Integer{
digits: operand_a[0..k]
digits: unsafe { operand_a[0..k] }
signum: 1
}
a1 := Integer{
digits: operand_a[k..k2]
digits: unsafe { operand_a[k..k2] }
signum: 1
}
a2 := Integer{
digits: operand_a[k2..]
digits: unsafe { operand_a[k2..] }
signum: 1
}

Expand Down

0 comments on commit 4dcc926

Please sign in to comment.