From 120f31b4d97e9761220218fdd35711f4e46d9cb1 Mon Sep 17 00:00:00 2001 From: David 'Epper' Marshall Date: Fri, 20 May 2022 01:45:54 -0400 Subject: [PATCH] math: update documentation (#14457) --- vlib/math/exp.v | 3 +- vlib/math/hypot.v | 1 + vlib/math/invhyp.v | 3 ++ vlib/math/log.v | 2 + vlib/math/math.v | 4 ++ vlib/math/sin.c.v | 4 +- vlib/math/sin.js.v | 4 +- vlib/math/sin.v | 7 +++- vlib/math/sinh.js.v | 4 +- vlib/math/sinh.v | 2 +- vlib/math/stats/stats.v | 80 ++++++++++++++++++------------------ vlib/math/unsigned/uint256.v | 45 +++++++++++++++++++- 12 files changed, 108 insertions(+), 51 deletions(-) diff --git a/vlib/math/exp.v b/vlib/math/exp.v index 9a6890b66..4e5f59e57 100644 --- a/vlib/math/exp.v +++ b/vlib/math/exp.v @@ -96,6 +96,7 @@ pub fn exp2(x f64) f64 { return expmulti(hi, lo, k) } +// ldexp calculates frac*(2**exp) pub fn ldexp(frac f64, exp int) f64 { return scalbn(frac, exp) } @@ -146,6 +147,7 @@ pub fn frexp(x f64) (f64, int) { return f64_from_bits(y), e_ } +// expm1 calculates e**x - 1 // special cases are: // expm1(+inf) = +inf // expm1(-inf) = -1 @@ -176,7 +178,6 @@ pub fn expm1(x f64) f64 { } } -// exp1 returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2. fn expmulti(hi f64, lo f64, k int) f64 { exp_p1 := 1.66666666666666657415e-01 // 0x3FC55555; 0x55555555 exp_p2 := -2.77777777770155933842e-03 // 0xBF66C16C; 0x16BEBD93 diff --git a/vlib/math/hypot.v b/vlib/math/hypot.v index 41375057b..c7cb9e54d 100644 --- a/vlib/math/hypot.v +++ b/vlib/math/hypot.v @@ -1,5 +1,6 @@ module math +// hypot returns the hypotenuse of the triangle give two sides pub fn hypot(x f64, y f64) f64 { if is_inf(x, 0) || is_inf(y, 0) { return inf(1) diff --git a/vlib/math/invhyp.v b/vlib/math/invhyp.v index 4ef93cbce..5884b4e5a 100644 --- a/vlib/math/invhyp.v +++ b/vlib/math/invhyp.v @@ -1,6 +1,7 @@ module math import math.internal +// acosh returns the non negative area hyperbolic cosine of x pub fn acosh(x f64) f64 { if x == 0.0 { @@ -19,6 +20,7 @@ pub fn acosh(x f64) f64 { } } +// asinh returns the area hyperbolic sine of x pub fn asinh(x f64) f64 { a := abs(x) s := if x < 0 { -1.0 } else { 1.0 } @@ -34,6 +36,7 @@ pub fn asinh(x f64) f64 { } } +// atanh returns the area hyperbolic tangent of x pub fn atanh(x f64) f64 { a := abs(x) s := if x < 0 { -1.0 } else { 1.0 } diff --git a/vlib/math/log.v b/vlib/math/log.v index f274d0fc2..da7eaedaa 100644 --- a/vlib/math/log.v +++ b/vlib/math/log.v @@ -1,5 +1,6 @@ module math +// log_n returns log base b of x pub fn log_n(x f64, b f64) f64 { y := log(x) z := log(b) @@ -24,6 +25,7 @@ pub fn log2(x f64) f64 { return log(frac) * (1.0 / ln2) + f64(exp) } +// log1p returns log(1+x) pub fn log1p(x f64) f64 { y := 1.0 + x z := y - 1.0 diff --git a/vlib/math/math.v b/vlib/math/math.v index 0d0d7a56f..71562b04d 100644 --- a/vlib/math/math.v +++ b/vlib/math/math.v @@ -155,6 +155,7 @@ pub fn signbit(x f64) bool { return f64_bits(x) & sign_mask != 0 } +// tolerance checks if a and b difference are less than or equal to the tolerance value pub fn tolerance(a f64, b f64, tol f64) bool { mut ee := tol // Multiplying by ee here can underflow denormal values to zero. @@ -178,14 +179,17 @@ pub fn tolerance(a f64, b f64, tol f64) bool { return d < ee } +// close checks if a and b are within 1e-14 of each other pub fn close(a f64, b f64) bool { return tolerance(a, b, 1e-14) } +// veryclose checks if a and b are within 4e-16 of each other pub fn veryclose(a f64, b f64) bool { return tolerance(a, b, 4e-16) } +// alike checks if a and b are equal pub fn alike(a f64, b f64) bool { if is_nan(a) && is_nan(b) { return true diff --git a/vlib/math/sin.c.v b/vlib/math/sin.c.v index 39a4b8518..ef313af18 100644 --- a/vlib/math/sin.c.v +++ b/vlib/math/sin.c.v @@ -4,13 +4,13 @@ fn C.cosf(x f32) f32 fn C.sinf(x f32) f32 -// cosf calculates cosine. (float32) +// cosf calculates cosine in radians (float32) [inline] pub fn cosf(a f32) f32 { return C.cosf(a) } -// sinf calculates sine. (float32) +// sinf calculates sine in radians (float32) [inline] pub fn sinf(a f32) f32 { return C.sinf(a) diff --git a/vlib/math/sin.js.v b/vlib/math/sin.js.v index 40ef854bf..ab6acf1fe 100644 --- a/vlib/math/sin.js.v +++ b/vlib/math/sin.js.v @@ -4,13 +4,13 @@ fn JS.Math.cos(x f64) f64 fn JS.Math.sin(x f64) f64 -// cos calculates cosine. +// cos calculates cosine in radians [inline] pub fn cos(a f64) f64 { return JS.Math.cos(a) } -// sin calculates sine. +// sin calculates sine in radians [inline] pub fn sin(a f64) f64 { return JS.Math.sin(a) diff --git a/vlib/math/sin.v b/vlib/math/sin.v index 193eb798a..a2a2e05d7 100644 --- a/vlib/math/sin.v +++ b/vlib/math/sin.v @@ -44,6 +44,7 @@ const ( } ) +// sin calculates the sine of the angle in radians pub fn sin(x f64) f64 { p1 := 7.85398125648498535156e-1 p2 := 3.77489470793079817668e-8 @@ -82,6 +83,7 @@ pub fn sin(x f64) f64 { } } +// cos calculates the cosine of the angle in radians pub fn cos(x f64) f64 { p1 := 7.85398125648498535156e-1 p2 := 3.77489470793079817668e-8 @@ -122,18 +124,19 @@ pub fn cos(x f64) f64 { } } -// cosf calculates cosine. (float32). +// cosf calculates cosine in radians (float32). [inline] pub fn cosf(a f32) f32 { return f32(cos(a)) } -// sinf calculates sine. (float32) +// sinf calculates sine in radians (float32) [inline] pub fn sinf(a f32) f32 { return f32(sin(a)) } +// sincos calculates the sine and cosine of the angle in radians pub fn sincos(x f64) (f64, f64) { p1 := 7.85398125648498535156e-1 p2 := 3.77489470793079817668e-8 diff --git a/vlib/math/sinh.js.v b/vlib/math/sinh.js.v index 8c7d72f5c..5fb0f5c6d 100644 --- a/vlib/math/sinh.js.v +++ b/vlib/math/sinh.js.v @@ -4,13 +4,13 @@ fn JS.Math.cosh(x f64) f64 fn JS.Math.sinh(x f64) f64 -// cosh calculates hyperbolic cosine. +// cosh calculates hyperbolic cosine in radians [inline] pub fn cosh(a f64) f64 { return JS.Math.cosh(a) } -// sinh calculates hyperbolic sine. +// sinh calculates hyperbolic sine in radians [inline] pub fn sinh(a f64) f64 { return JS.Math.sinh(a) diff --git a/vlib/math/sinh.v b/vlib/math/sinh.v index 6bbf88088..bfb818f22 100644 --- a/vlib/math/sinh.v +++ b/vlib/math/sinh.v @@ -33,7 +33,7 @@ pub fn sinh(x_ f64) f64 { return temp } -// cosh returns the hyperbolic cosine of x. +// cosh returns the hyperbolic cosine of x in radians // // special cases are: // cosh(±0) = 1 diff --git a/vlib/math/stats/stats.v b/vlib/math/stats/stats.v index 544391019..2b19e613d 100644 --- a/vlib/math/stats/stats.v +++ b/vlib/math/stats/stats.v @@ -2,7 +2,7 @@ module stats import math -// Measure of Occurance +// freq calculates the Measure of Occurance // Frequency of a given number // Based on // https://www.mathsisfun.com/data/frequency-distribution.html @@ -19,8 +19,8 @@ pub fn freq(data []T, val T) int { return count } -// Measure of Central Tendancy -// Mean of the given input array +// mean calculates the average +// of the given input array, sum(data)/data.len // Based on // https://www.mathsisfun.com/data/central-measures.html pub fn mean(data []T) T { @@ -34,8 +34,8 @@ pub fn mean(data []T) T { return sum / T(data.len) } -// Measure of Central Tendancy -// Geometric Mean of the given input array +// geometric_mean calculates the central tendency +// of the given input array, product(data)**1/data.len // Based on // https://www.mathsisfun.com/numbers/geometric-mean.html pub fn geometric_mean(data []T) T { @@ -49,8 +49,8 @@ pub fn geometric_mean(data []T) T { return math.pow(sum, 1.0 / T(data.len)) } -// Measure of Central Tendancy -// Harmonic Mean of the given input array +// harmonic_mean calculates the reciprocal of the average of reciprocals +// of the given input array // Based on // https://www.mathsisfun.com/numbers/harmonic-mean.html pub fn harmonic_mean(data []T) T { @@ -64,8 +64,7 @@ pub fn harmonic_mean(data []T) T { return T(data.len) / sum } -// Measure of Central Tendancy -// Median of the given input array ( input array is assumed to be sorted ) +// median returns the middlemost value of the given input array ( input array is assumed to be sorted ) // Based on // https://www.mathsisfun.com/data/central-measures.html pub fn median(sorted_data []T) T { @@ -80,8 +79,7 @@ pub fn median(sorted_data []T) T { } } -// Measure of Central Tendancy -// Mode of the given input array +// mode calculates the highest occuring value of the given input array // Based on // https://www.mathsisfun.com/data/central-measures.html pub fn mode(data []T) T { @@ -101,7 +99,7 @@ pub fn mode(data []T) T { return data[max] } -// Root Mean Square of the given input array +// rms, Root Mean Square, calculates the sqrt of the mean of the squares of the given input array // Based on // https://en.wikipedia.org/wiki/Root_mean_square pub fn rms(data []T) T { @@ -115,8 +113,8 @@ pub fn rms(data []T) T { return math.sqrt(sum / T(data.len)) } -// Measure of Dispersion / Spread -// Population Variance of the given input array +// population_variance is the Measure of Dispersion / Spread +// of the given input array // Based on // https://www.mathsisfun.com/data/standard-deviation.html [inline] @@ -128,8 +126,8 @@ pub fn population_variance(data []T) T { return population_variance_mean(data, data_mean) } -// Measure of Dispersion / Spread -// Population Variance of the given input array +// population_variance_mean is the Measure of Dispersion / Spread +// of the given input array, with the provided mean // Based on // https://www.mathsisfun.com/data/standard-deviation.html pub fn population_variance_mean(data []T, mean T) T { @@ -143,8 +141,7 @@ pub fn population_variance_mean(data []T, mean T) T { return sum / T(data.len) } -// Measure of Dispersion / Spread -// Sample Variance of the given input array +// sample_variance calculates the spread of dataset around the mean // Based on // https://www.mathsisfun.com/data/standard-deviation.html [inline] @@ -156,8 +153,7 @@ pub fn sample_variance(data []T) T { return sample_variance_mean(data, data_mean) } -// Measure of Dispersion / Spread -// Sample Variance of the given input array +// sample_variance calculates the spread of dataset around the provided mean // Based on // https://www.mathsisfun.com/data/standard-deviation.html pub fn sample_variance_mean(data []T, mean T) T { @@ -171,8 +167,7 @@ pub fn sample_variance_mean(data []T, mean T) T { return sum / T(data.len - 1) } -// Measure of Dispersion / Spread -// Population Standard Deviation of the given input array +// population_stddev calculates how spread out the dataset is // Based on // https://www.mathsisfun.com/data/standard-deviation.html [inline] @@ -183,8 +178,7 @@ pub fn population_stddev(data []T) T { return math.sqrt(population_variance(data)) } -// Measure of Dispersion / Spread -// Population Standard Deviation of the given input array +// population_stddev_mean calculates how spread out the dataset is, with the provide mean // Based on // https://www.mathsisfun.com/data/standard-deviation.html [inline] @@ -219,8 +213,7 @@ pub fn sample_stddev_mean(data []T, mean T) T { return T(math.sqrt(f64(sample_variance_mean(data, mean)))) } -// Measure of Dispersion / Spread -// Mean Absolute Deviation of the given input array +// absdev calculates the average distance between each data point and the mean // Based on // https://en.wikipedia.org/wiki/Average_absolute_deviation [inline] @@ -232,8 +225,7 @@ pub fn absdev(data []T) T { return absdev_mean(data, data_mean) } -// Measure of Dispersion / Spread -// Mean Absolute Deviation of the given input array +// absdev_mean calculates the average distance between each data point and the provided mean // Based on // https://en.wikipedia.org/wiki/Average_absolute_deviation pub fn absdev_mean(data []T, mean T) T { @@ -247,7 +239,7 @@ pub fn absdev_mean(data []T, mean T) T { return sum / T(data.len) } -// Sum of squares +// tts, Sum of squares, calculates the sum over all squared differences between values and overall mean [inline] pub fn tss(data []T) T { if data.len == 0 { @@ -257,7 +249,7 @@ pub fn tss(data []T) T { return tss_mean(data, data_mean) } -// Sum of squares about the mean +// tts_mean, Sum of squares, calculates the sum over all squared differences between values and the provided mean pub fn tss_mean(data []T, mean T) T { if data.len == 0 { return T(0) @@ -269,7 +261,7 @@ pub fn tss_mean(data []T, mean T) T { return tss } -// Minimum of the given input array +// min finds the minimum value from the dataset pub fn min(data []T) T { if data.len == 0 { return T(0) @@ -283,7 +275,7 @@ pub fn min(data []T) T { return min } -// Maximum of the given input array +// max finds the maximum value from the dataset pub fn max(data []T) T { if data.len == 0 { return T(0) @@ -297,7 +289,7 @@ pub fn max(data []T) T { return max } -// Minimum and maximum of the given input array +// minmax finds the minimum and maximum value from the dataset pub fn minmax(data []T) (T, T) { if data.len == 0 { return T(0), T(0) @@ -315,7 +307,7 @@ pub fn minmax(data []T) (T, T) { return min, max } -// Minimum of the given input array +// min_index finds the first index of the minimum value pub fn min_index(data []T) int { if data.len == 0 { return 0 @@ -331,7 +323,7 @@ pub fn min_index(data []T) int { return min_index } -// Maximum of the given input array +// max_index finds the first index of the maximum value pub fn max_index(data []T) int { if data.len == 0 { return 0 @@ -347,7 +339,7 @@ pub fn max_index(data []T) int { return max_index } -// Minimum and maximum of the given input array +// minmax_index finds the first index of the minimum and maximum value pub fn minmax_index(data []T) (int, int) { if data.len == 0 { return 0, 0 @@ -369,7 +361,7 @@ pub fn minmax_index(data []T) (int, int) { return min_index, max_index } -// Measure of Dispersion / Spread +// range calculates the difference between the min and max // Range ( Maximum - Minimum ) of the given input array // Based on // https://www.mathsisfun.com/data/range.html @@ -381,6 +373,8 @@ pub fn range(data []T) T { return max - min } +// covariance calculates directional association between datasets +// positive value denotes variables move in same direction and negative denotes variables move in opposite directions [inline] pub fn covariance(data1 []T, data2 []T) T { mean1 := mean(data1) @@ -388,7 +382,7 @@ pub fn covariance(data1 []T, data2 []T) T { return covariance_mean(data1, data2, mean1, mean2) } -// Compute the covariance of a dataset using +// covariance_mean computes the covariance of a dataset with means provided // the recurrence relation pub fn covariance_mean(data1 []T, data2 []T, mean1 T, mean2 T) T { n := int(math.min(data1.len, data2.len)) @@ -404,13 +398,16 @@ pub fn covariance_mean(data1 []T, data2 []T, mean1 T, mean2 T) T { return covariance } +// lag1_autocorrelation_mean calculates the correlation between values that are one time period apart +// of a dataset, based on the mean [inline] pub fn lag1_autocorrelation(data []T) T { data_mean := mean(data) return lag1_autocorrelation_mean(data, data_mean) } -// Compute the lag-1 autocorrelation of a dataset using +// lag1_autocorrelation_mean calculates the correlation between values that are one time period apart +// of a dataset, using // the recurrence relation pub fn lag1_autocorrelation_mean(data []T, mean T) T { if data.len == 0 { @@ -427,6 +424,7 @@ pub fn lag1_autocorrelation_mean(data []T, mean T) T { return q / v } +// kurtosis calculates the measure of the 'tailedness' of the data by finding mean and standard of deviation [inline] pub fn kurtosis(data []T) T { data_mean := mean(data) @@ -434,7 +432,7 @@ pub fn kurtosis(data []T) T { return kurtosis_mean_stddev(data, data_mean, sd) } -// Takes a dataset and finds the kurtosis +// kurtosis_mean_stddev calculates the measure of the 'tailedness' of the data // using the fourth moment the deviations, normalized by the sd pub fn kurtosis_mean_stddev(data []T, mean T, sd T) T { mut avg := T(0) // find the fourth moment the deviations, normalized by the sd @@ -449,6 +447,7 @@ pub fn kurtosis_mean_stddev(data []T, mean T, sd T) T { return avg - T(3.0) } +// skew calculates the mean and standard of deviation to find the skew from the data [inline] pub fn skew(data []T) T { data_mean := mean(data) @@ -456,6 +455,7 @@ pub fn skew(data []T) T { return skew_mean_stddev(data, data_mean, sd) } +// skew_mean_stddev calculates the skewness of data pub fn skew_mean_stddev(data []T, mean T, sd T) T { mut skew := T(0) // find the sum of the cubed deviations, normalized by the sd. /* diff --git a/vlib/math/unsigned/uint256.v b/vlib/math/unsigned/uint256.v index 8b1d6dc0a..37645b671 100644 --- a/vlib/math/unsigned/uint256.v +++ b/vlib/math/unsigned/uint256.v @@ -14,26 +14,32 @@ pub mut: hi Uint128 = uint128_zero // upper 128 bit half } +// uint256_from_128 creates a new `unsigned.Uint256` from the given Uint128 value pub fn uint256_from_128(v Uint128) Uint256 { return Uint256{v, uint128_zero} } +// uint256_from_64 creates a new `unsigned.Uint256` from the given u64 value pub fn uint256_from_64(v u64) Uint256 { return uint256_from_128(uint128_from_64(v)) } +// is_zero checks if specified Uint256 is zero pub fn (u Uint256) is_zero() bool { return u.lo.is_zero() && u.hi.is_zero() } +// equals checks if the two Uint256 values match one another pub fn (u Uint256) equals(v Uint256) bool { return u.lo.equals(v.lo) && u.hi.equals(v.hi) } -pub fn (u Uint256) euqals_128(v Uint128) bool { +// equals_128 checks if the Uint256 value matches the Uint128 value +pub fn (u Uint256) equals_128(v Uint128) bool { return u.lo.equals(v) && u.hi.is_zero() } +// cmp returns 1 if u is greater than v, -1 if u is less than v, or 0 if equal pub fn (u Uint256) cmp(v Uint256) int { h := u.hi.cmp(v.hi) if h != 0 { @@ -42,6 +48,7 @@ pub fn (u Uint256) cmp(v Uint256) int { return u.lo.cmp(v.lo) } +// cmp_128 returns 1 if u is greater than v (Uint128), -1 if u is less than v, or 0 if equal pub fn (u Uint256) cmp_128(v Uint128) int { if !u.hi.is_zero() { return 1 @@ -49,34 +56,42 @@ pub fn (u Uint256) cmp_128(v Uint128) int { return u.lo.cmp(v) } +// not returns a binary negation of the Uint256 value pub fn (u Uint256) not() Uint256 { return Uint256{u.lo.not(), u.hi.not()} } +// and returns a Uint256 value that is the bitwise and of u and v pub fn (u Uint256) and(v Uint256) Uint256 { return Uint256{u.lo.and(v.lo), u.hi.and(v.hi)} } +// and_128 returns a Uint256 value that is the bitwise and of u and v, which is a Uint128 pub fn (u Uint256) and_128(v Uint128) Uint256 { return Uint256{u.lo.and(v), uint128_zero} } +// or_ returns a Uint256 value that is the bitwise or of u and v pub fn (u Uint256) or_(v Uint256) Uint256 { return Uint256{u.lo.or_(v.lo), u.hi.or_(v.hi)} } +// or_128 returns a Uint256 value that is the bitwise or of u and v, which is a Uint128 pub fn (u Uint256) or_128(v Uint128) Uint256 { return Uint256{u.lo.or_(v), u.hi} } +// xor returns a Uint256 value that is the bitwise xor of u and v pub fn (u Uint256) xor(v Uint256) Uint256 { return Uint256{u.lo.xor(v.lo), u.hi.xor(v.hi)} } +// xor_128 returns a Uint256 value that is the bitwise xor of u and v, which is a Uint128 pub fn (u Uint256) xor_128(v Uint128) Uint256 { return Uint256{u.lo.xor(v), u.hi} } +// add_256 - untested pub fn add_256(x Uint256, y Uint256, carry u64) (Uint256, u64) { mut sum := Uint256{} mut carry_out := u64(0) @@ -85,6 +100,7 @@ pub fn add_256(x Uint256, y Uint256, carry u64) (Uint256, u64) { return sum, carry_out } +// sub_256 - untested pub fn sub_256(x Uint256, y Uint256, borrow u64) (Uint256, u64) { mut diff := Uint256{} mut borrow_out := u64(0) @@ -93,6 +109,7 @@ pub fn sub_256(x Uint256, y Uint256, borrow u64) (Uint256, u64) { return diff, borrow_out } +// mul_256 - untested pub fn mul_256(x Uint256, y Uint256) (Uint256, Uint256) { mut hi := Uint256{} mut lo := Uint256{} @@ -114,31 +131,37 @@ pub fn mul_256(x Uint256, y Uint256) (Uint256, Uint256) { return hi, lo } +// add returns a Uint256 that is equal to u+v pub fn (u Uint256) add(v Uint256) Uint256 { sum, _ := add_256(u, v, 0) return sum } +// overflowing_add - untested pub fn (u Uint256) overflowing_add(v Uint256) (Uint256, u64) { sum, overflow := add_256(u, v, 0) return sum, overflow } +// add_128 returns a Uint256 that is equal to u+v, v being a Uint128 pub fn (u Uint256) add_128(v Uint128) Uint256 { lo, c0 := add_128(u.lo, v, 0) return Uint256{lo, u.hi.add_64(c0)} } +// sub returns a Uint256 that is equal to u-v pub fn (u Uint256) sub(v Uint256) Uint256 { diff, _ := sub_256(u, v, 0) return diff } +// sub_128 returns a Uint256 that is equal to u-v, v being a Uint128 pub fn (u Uint256) sub_128(v Uint128) Uint256 { lo, b0 := sub_128(u.lo, v, 0) return Uint256{lo, u.hi.sub_64(b0)} } +// mul returns a Uint256 that is eqal to u*v pub fn (u Uint256) mul(v Uint256) Uint256 { mut hi, mut lo := mul_128(u.lo, v.lo) hi = hi.add(u.hi.mul(v.lo)) @@ -146,11 +169,13 @@ pub fn (u Uint256) mul(v Uint256) Uint256 { return Uint256{lo, hi} } +// mul_128 returns a Uint256 that is eqal to u*v, v being a Uint128 pub fn (u Uint256) mul_128(v Uint128) Uint256 { hi, lo := mul_128(u.lo, v) return Uint256{lo, hi.add(u.hi.mul(v))} } +// quo_rem - untested pub fn (u Uint256) quo_rem(v Uint256) (Uint256, Uint256) { if v.hi.is_zero() { q, r := u.quo_rem_128(v.lo) @@ -173,6 +198,7 @@ pub fn (u Uint256) quo_rem(v Uint256) (Uint256, Uint256) { return q, r } +// quo_rem_128 - untested pub fn (u Uint256) quo_rem_128(v Uint128) (Uint256, Uint128) { if u.hi.cmp(v) < 0 { lo, r := div_128(u.hi, u.lo, v) @@ -184,6 +210,7 @@ pub fn (u Uint256) quo_rem_128(v Uint128) (Uint256, Uint128) { return Uint256{lo, hi}, r2 } +// quo_rem_64 - untested pub fn (u Uint256) quo_rem_64(v u64) (Uint256, u64) { mut q := Uint256{} mut r := u64(0) @@ -192,6 +219,7 @@ pub fn (u Uint256) quo_rem_64(v u64) (Uint256, u64) { return q, r } +// rsh returns a new Uint256 that has been right bit shifted pub fn (u Uint256) rsh(n_ u32) Uint256 { mut n := n_ if n > 128 { @@ -205,6 +233,7 @@ pub fn (u Uint256) rsh(n_ u32) Uint256 { return Uint256{Uint128{u.lo.lo >> n | u.lo.hi << (64 - n), u.lo.hi >> n | u.hi.lo << (64 - n)}, Uint128{u.hi.lo >> n | u.hi.hi << (64 - n), u.hi.hi >> n}} } +// lsh returns a new Uint256 that has been left bit shifted pub fn (u Uint256) lsh(n_ u32) Uint256 { mut n := n_ if n > 128 { @@ -219,36 +248,43 @@ pub fn (u Uint256) lsh(n_ u32) Uint256 { return Uint256{Uint128{u.lo.lo << n, u.lo.hi << n | u.lo.lo >> (64 - n)}, Uint128{u.hi.lo << n | u.lo.hi >> (64 - n), u.hi.hi << n | u.hi.lo >> (64 - n)}} } +// div - untested pub fn (u Uint256) div(v Uint256) Uint256 { q, _ := u.quo_rem(v) return q } +// div_128 - untested pub fn (u Uint256) div_128(v Uint128) Uint256 { q, _ := u.quo_rem_128(v) return q } +// div_64 - untested pub fn (u Uint256) div_64(v u64) Uint256 { q, _ := u.quo_rem_64(v) return q } +// mod - untested pub fn (u Uint256) mod(v Uint256) Uint256 { _, r := u.quo_rem(v) return r } +// mod_128 - untested pub fn (u Uint256) mod_128(v Uint128) Uint128 { _, r := u.quo_rem_128(v) return r } +// mod_64 - untested pub fn (u Uint256) mod_64(v u64) u64 { _, r := u.quo_rem_64(v) return r } +// rotate_left returns a new Uint256 that has been left bit shifted pub fn (u Uint256) rotate_left(k int) Uint256 { mut n := u32(k) & 255 if n < 64 { @@ -283,10 +319,12 @@ pub fn (u Uint256) rotate_left(k int) Uint256 { return Uint256{Uint128{u.lo.hi << n | u.lo.lo >> (64 - n), u.hi.lo << n | u.lo.hi >> (64 - n)}, Uint128{u.hi.hi << n | u.hi.lo >> (64 - n), u.lo.lo << n | u.hi.hi >> (64 - n)}} } +// rotate_right returns a new Uint256 that has been right bit shifted pub fn (u Uint256) rotate_right(k int) Uint256 { return u.rotate_left(-k) } +// len returns the length of the binary value without the leading zeros pub fn (u Uint256) len() int { if !u.hi.is_zero() { return 128 + u.hi.len() @@ -294,6 +332,7 @@ pub fn (u Uint256) len() int { return u.lo.len() } +// leading_zeros returns the number of 0s at the beginning of the binary value of the Uint256 value [0, 256] pub fn (u Uint256) leading_zeros() int { if !u.hi.is_zero() { return u.hi.leading_zeros() @@ -301,6 +340,7 @@ pub fn (u Uint256) leading_zeros() int { return 128 + u.lo.leading_zeros() } +// trailing_zeros returns the number of 0s at the end of the binary value of the Uint256 value [0,256] pub fn (u Uint256) trailing_zeros() int { if !u.lo.is_zero() { return u.lo.trailing_zeros() @@ -309,10 +349,12 @@ pub fn (u Uint256) trailing_zeros() int { return 128 + u.hi.trailing_zeros() } +// ones_count returns the number of ones in the binary value of the Uint256 value pub fn (u Uint256) ones_count() int { return u.lo.ones_count() + u.hi.ones_count() } +// str returns the decimal representation of the unsigned integer pub fn (u_ Uint256) str() string { mut u := u_ if u.hi.is_zero() { @@ -339,6 +381,7 @@ pub fn (u_ Uint256) str() string { return '' } +// uint256_from_dec_str creates a new `unsigned.Uint256` from the given string if possible pub fn uint256_from_dec_str(value string) ?Uint256 { mut res := unsigned.uint256_zero for b_ in value.bytes() { -- 2.30.2