math: update documentation (#14457)

master
David 'Epper' Marshall 2022-05-20 01:45:54 -04:00 committed by GitHub
parent 23568f19da
commit 120f31b4d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 51 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 }

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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<T>(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<T>(data []T) T {
@ -34,8 +34,8 @@ pub fn mean<T>(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<T>(data []T) T {
@ -49,8 +49,8 @@ pub fn geometric_mean<T>(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<T>(data []T) T {
@ -64,8 +64,7 @@ pub fn harmonic_mean<T>(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<T>(sorted_data []T) T {
@ -80,8 +79,7 @@ pub fn median<T>(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<T>(data []T) T {
@ -101,7 +99,7 @@ pub fn mode<T>(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<T>(data []T) T {
@ -115,8 +113,8 @@ pub fn rms<T>(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<T>(data []T) T {
return population_variance_mean<T>(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<T>(data []T, mean T) T {
@ -143,8 +141,7 @@ pub fn population_variance_mean<T>(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<T>(data []T) T {
return sample_variance_mean<T>(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<T>(data []T, mean T) T {
@ -171,8 +167,7 @@ pub fn sample_variance_mean<T>(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<T>(data []T) T {
return math.sqrt(population_variance<T>(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<T>(data []T, mean T) T {
return T(math.sqrt(f64(sample_variance_mean<T>(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<T>(data []T) T {
return absdev_mean<T>(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<T>(data []T, mean T) T {
@ -247,7 +239,7 @@ pub fn absdev_mean<T>(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<T>(data []T) T {
if data.len == 0 {
@ -257,7 +249,7 @@ pub fn tss<T>(data []T) T {
return tss_mean<T>(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<T>(data []T, mean T) T {
if data.len == 0 {
return T(0)
@ -269,7 +261,7 @@ pub fn tss_mean<T>(data []T, mean T) T {
return tss
}
// Minimum of the given input array
// min finds the minimum value from the dataset
pub fn min<T>(data []T) T {
if data.len == 0 {
return T(0)
@ -283,7 +275,7 @@ pub fn min<T>(data []T) T {
return min
}
// Maximum of the given input array
// max finds the maximum value from the dataset
pub fn max<T>(data []T) T {
if data.len == 0 {
return T(0)
@ -297,7 +289,7 @@ pub fn max<T>(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<T>(data []T) (T, T) {
if data.len == 0 {
return T(0), T(0)
@ -315,7 +307,7 @@ pub fn minmax<T>(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<T>(data []T) int {
if data.len == 0 {
return 0
@ -331,7 +323,7 @@ pub fn min_index<T>(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<T>(data []T) int {
if data.len == 0 {
return 0
@ -347,7 +339,7 @@ pub fn max_index<T>(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<T>(data []T) (int, int) {
if data.len == 0 {
return 0, 0
@ -369,7 +361,7 @@ pub fn minmax_index<T>(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<T>(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<T>(data1 []T, data2 []T) T {
mean1 := mean<T>(data1)
@ -388,7 +382,7 @@ pub fn covariance<T>(data1 []T, data2 []T) T {
return covariance_mean<T>(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<T>(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<T>(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<T>(data []T) T {
data_mean := mean<T>(data)
return lag1_autocorrelation_mean<T>(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<T>(data []T, mean T) T {
if data.len == 0 {
@ -427,6 +424,7 @@ pub fn lag1_autocorrelation_mean<T>(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<T>(data []T) T {
data_mean := mean<T>(data)
@ -434,7 +432,7 @@ pub fn kurtosis<T>(data []T) T {
return kurtosis_mean_stddev<T>(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<T>(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<T>(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<T>(data []T) T {
data_mean := mean<T>(data)
@ -456,6 +455,7 @@ pub fn skew<T>(data []T) T {
return skew_mean_stddev<T>(data, data_mean, sd)
}
// skew_mean_stddev calculates the skewness of data
pub fn skew_mean_stddev<T>(data []T, mean T, sd T) T {
mut skew := T(0) // find the sum of the cubed deviations, normalized by the sd.
/*

View File

@ -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() {