mirror of
https://github.com/vlang/v.git
synced 2025-09-11 16:36:20 -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
|
// a < b => q, r = 0, a
|
||||||
if cmp_result < 0 {
|
if cmp_result < 0 {
|
||||||
quotient.clear()
|
quotient.clear()
|
||||||
for index in 0 .. operand_a.len {
|
remainder << operand_a
|
||||||
remainder << operand_a[index]
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if operand_b.len == 1 {
|
if operand_b.len == 1 {
|
||||||
|
@ -6,9 +6,7 @@ import math.bits
|
|||||||
// Both quotient and remaider are allocated but of length 0
|
// Both quotient and remaider are allocated but of length 0
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn binary_divide_array_by_array(operand_a []u32, operand_b []u32, mut quotient []u32, mut remainder []u32) {
|
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
|
||||||
remainder << operand_a[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
len_diff := operand_a.len - operand_b.len
|
len_diff := operand_a.len - operand_b.len
|
||||||
$if debug {
|
$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 {
|
for _ in 0 .. len_diff {
|
||||||
divisor << u32(0)
|
divisor << u32(0)
|
||||||
}
|
}
|
||||||
for index in 0 .. operand_b.len {
|
divisor << operand_b
|
||||||
divisor << operand_b[index]
|
|
||||||
}
|
|
||||||
for _ in 0 .. len_diff + 1 {
|
for _ in 0 .. len_diff + 1 {
|
||||||
quotient << u32(0)
|
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.
|
// == returns `true` if the integers `a` and `b` are equal in value and sign.
|
||||||
|
@[inline]
|
||||||
pub fn (a Integer) == (b Integer) bool {
|
pub fn (a Integer) == (b Integer) bool {
|
||||||
return a.signum == b.signum && a.digits.len == b.digits.len && a.digits == b.digits
|
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`.
|
// 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|`.
|
// 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 {
|
pub fn (a Integer) abs_cmp(b Integer) int {
|
||||||
return compare_digit_array(a.digits, b.digits)
|
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`.
|
// int returns the integer value of the integer `a`.
|
||||||
// NOTE: This may cause loss of precision.
|
// NOTE: This may cause loss of precision.
|
||||||
|
@[direct_array_access]
|
||||||
pub fn (a Integer) int() int {
|
pub fn (a Integer) int() int {
|
||||||
if a.signum == 0 {
|
if a.signum == 0 {
|
||||||
return 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
|
// thanks to the base cases we can pass zero-length arrays to the mult func
|
||||||
half := imax(operand_a.len, operand_b.len) / 2
|
half := imax(operand_a.len, operand_b.len) / 2
|
||||||
a_l := operand_a[0..half]
|
a_l := unsafe { operand_a[0..half] }
|
||||||
a_h := operand_a[half..]
|
a_h := unsafe { operand_a[half..] }
|
||||||
mut b_l := []u32{}
|
mut b_l := []u32{}
|
||||||
mut b_h := []u32{}
|
mut b_h := []u32{}
|
||||||
if half <= operand_b.len {
|
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
|
// Slices of a and b
|
||||||
a0 := Integer{
|
a0 := Integer{
|
||||||
digits: operand_a[0..k]
|
digits: unsafe { operand_a[0..k] }
|
||||||
signum: 1
|
signum: 1
|
||||||
}
|
}
|
||||||
a1 := Integer{
|
a1 := Integer{
|
||||||
digits: operand_a[k..k2]
|
digits: unsafe { operand_a[k..k2] }
|
||||||
signum: 1
|
signum: 1
|
||||||
}
|
}
|
||||||
a2 := Integer{
|
a2 := Integer{
|
||||||
digits: operand_a[k2..]
|
digits: unsafe { operand_a[k2..] }
|
||||||
signum: 1
|
signum: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user