From aca3797f2371868e354abb68edc641e6210df9ce Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 18 Feb 2026 14:06:17 +0200 Subject: [PATCH] examples: improve pidigits.v using a much faster spigot algorithm from https://mail.python.org/pipermail/edu-sig/2012-December/010721.html --- examples/pidigits.v | 66 +++++++++++-------------------------- vlib/math/big/big.v | 46 ++++++++++++++++++-------- vlib/math/big/consts_test.v | 32 ++++++++++++++++++ 3 files changed, 84 insertions(+), 60 deletions(-) create mode 100644 vlib/math/big/consts_test.v diff --git a/examples/pidigits.v b/examples/pidigits.v index 85265cb87..27e462313 100644 --- a/examples/pidigits.v +++ b/examples/pidigits.v @@ -1,52 +1,26 @@ -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 +// pi_digits calculates the digits of Pi, based on https://mail.python.org/pipermail/edu-sig/2012-December/010721.html +fn pi_digits(count int) { + mut n := count + mut k, mut a, mut b, mut a1, mut b1 := big.c2, big.c4, big.c1, big.c12, big.c4 + mut p, mut q := k, k + for n > 0 { + p, q, k = k * k, (big.c2 * k) + big.c1, k + big.c1 + a, b, a1, b1 = a1, b1, p * a + q * a1, p * b + q * b1 + mut d := a / b + mut d1 := a1 / b1 + for d == d1 { + print(d.int()) + n-- + a, a1 = big.c10 * (a % b), big.c10 * (a1 % b1) + d, d1 = a / b, a1 / b1 + if n <= 0 { + break } - 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 } } } + +pi_digits(arguments()[1] or { '100' }.int()) +println('') diff --git a/vlib/math/big/big.v b/vlib/math/big/big.v index 2c0cb7ab4..4a9357089 100644 --- a/vlib/math/big/big.v +++ b/vlib/math/big/big.v @@ -5,18 +5,36 @@ pub const zero_int = Integer{ signum: 0 is_const: true } -pub const one_int = Integer{ - digits: [u64(1)] - signum: 1 - is_const: true -} -pub const two_int = Integer{ - digits: [u64(2)] - signum: 1 - is_const: true -} -pub const three_int = Integer{ - digits: [u64(3)] - signum: 1 - is_const: true +pub const one_int = positive_integer(1) +pub const two_int = positive_integer(2) +pub const three_int = positive_integer(3) + +pub const c0 = zero_int +pub const c1 = positive_integer(1) +pub const c2 = positive_integer(2) +pub const c3 = positive_integer(3) +pub const c4 = positive_integer(4) +pub const c5 = positive_integer(5) +pub const c6 = positive_integer(6) +pub const c7 = positive_integer(7) +pub const c8 = positive_integer(8) +pub const c9 = positive_integer(9) +pub const c10 = positive_integer(10) +pub const c11 = positive_integer(11) +pub const c12 = positive_integer(12) +pub const c13 = positive_integer(13) +pub const c14 = positive_integer(14) +pub const c15 = positive_integer(15) +pub const c16 = positive_integer(16) +pub const c17 = positive_integer(17) +pub const c18 = positive_integer(18) +pub const c19 = positive_integer(19) +pub const c20 = positive_integer(20) + +fn positive_integer(x int) Integer { + return Integer{ + digits: [u64(x)] + signum: 1 + is_const: true + } } diff --git a/vlib/math/big/consts_test.v b/vlib/math/big/consts_test.v new file mode 100644 index 000000000..74edeb546 --- /dev/null +++ b/vlib/math/big/consts_test.v @@ -0,0 +1,32 @@ +import math.big + +fn test_named_consts() { + assert big.zero_int == big.integer_from_int(0) + assert big.one_int == big.integer_from_int(1) + assert big.two_int == big.integer_from_int(2) + assert big.three_int == big.integer_from_int(3) +} + +fn test_indexed_consts() { + assert big.c0 == big.integer_from_int(0) + assert big.c1 == big.integer_from_int(1) + assert big.c2 == big.integer_from_int(2) + assert big.c3 == big.integer_from_int(3) + assert big.c4 == big.integer_from_int(4) + assert big.c5 == big.integer_from_int(5) + assert big.c6 == big.integer_from_int(6) + assert big.c7 == big.integer_from_int(7) + assert big.c8 == big.integer_from_int(8) + assert big.c9 == big.integer_from_int(9) + assert big.c10 == big.integer_from_int(10) + assert big.c11 == big.integer_from_int(11) + assert big.c12 == big.integer_from_int(12) + assert big.c13 == big.integer_from_int(13) + assert big.c14 == big.integer_from_int(14) + assert big.c15 == big.integer_from_int(15) + assert big.c16 == big.integer_from_int(16) + assert big.c17 == big.integer_from_int(17) + assert big.c18 == big.integer_from_int(18) + assert big.c19 == big.integer_from_int(19) + assert big.c20 == big.integer_from_int(20) +} -- 2.39.5