mirror of
https://github.com/vlang/v.git
synced 2025-09-08 14:51:53 -04:00
examples: add pidigits.v; optimise math.big's Integer divide a bit (#21239)
This commit is contained in:
parent
d25e349020
commit
4dcc9265e1
52
examples/pidigits.v
Normal file
52
examples/pidigits.v
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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 {
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
@ -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
|
||||
|
@ -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 {
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user