diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2022-11-24 13:14:34 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2022-11-24 14:46:00 +0300 |
commit | 87f7fceed34bcafb8aaff351dd493a35c916986f (patch) | |
tree | 26809ec8f550aba8eb019e59adc3d48e51913eb2 /contrib/go/_std_1.18/src/math | |
parent | 11bc4015b8010ae201bf3eb33db7dba425aca35e (diff) | |
download | ydb-38c0b87ea9b8ab54a793f4246ecdee802a8227dc.tar.gz |
Ydb stable 22-4-4322.4.43
x-stable-origin-commit: 8d49d46cc834835bf3e50870516acd7376a63bcf
Diffstat (limited to 'contrib/go/_std_1.18/src/math')
92 files changed, 17857 insertions, 0 deletions
diff --git a/contrib/go/_std_1.18/src/math/abs.go b/contrib/go/_std_1.18/src/math/abs.go new file mode 100644 index 0000000000..df83add695 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/abs.go @@ -0,0 +1,14 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Abs returns the absolute value of x. +// +// Special cases are: +// Abs(±Inf) = +Inf +// Abs(NaN) = NaN +func Abs(x float64) float64 { + return Float64frombits(Float64bits(x) &^ (1 << 63)) +} diff --git a/contrib/go/_std_1.18/src/math/acosh.go b/contrib/go/_std_1.18/src/math/acosh.go new file mode 100644 index 0000000000..f74e0b62fb --- /dev/null +++ b/contrib/go/_std_1.18/src/math/acosh.go @@ -0,0 +1,64 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/e_acosh.c +// and came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// +// __ieee754_acosh(x) +// Method : +// Based on +// acosh(x) = log [ x + sqrt(x*x-1) ] +// we have +// acosh(x) := log(x)+ln2, if x is large; else +// acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else +// acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. +// +// Special cases: +// acosh(x) is NaN with signal if x<1. +// acosh(NaN) is NaN without signal. +// + +// Acosh returns the inverse hyperbolic cosine of x. +// +// Special cases are: +// Acosh(+Inf) = +Inf +// Acosh(x) = NaN if x < 1 +// Acosh(NaN) = NaN +func Acosh(x float64) float64 { + if haveArchAcosh { + return archAcosh(x) + } + return acosh(x) +} + +func acosh(x float64) float64 { + const Large = 1 << 28 // 2**28 + // first case is special case + switch { + case x < 1 || IsNaN(x): + return NaN() + case x == 1: + return 0 + case x >= Large: + return Log(x) + Ln2 // x > 2**28 + case x > 2: + return Log(2*x - 1/(x+Sqrt(x*x-1))) // 2**28 > x > 2 + } + t := x - 1 + return Log1p(t + Sqrt(2*t+t*t)) // 2 >= x > 1 +} diff --git a/contrib/go/_std_1.18/src/math/asin.go b/contrib/go/_std_1.18/src/math/asin.go new file mode 100644 index 0000000000..989a74155b --- /dev/null +++ b/contrib/go/_std_1.18/src/math/asin.go @@ -0,0 +1,65 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point arcsine and arccosine. + + They are implemented by computing the arctangent + after appropriate range reduction. +*/ + +// Asin returns the arcsine, in radians, of x. +// +// Special cases are: +// Asin(±0) = ±0 +// Asin(x) = NaN if x < -1 or x > 1 +func Asin(x float64) float64 { + if haveArchAsin { + return archAsin(x) + } + return asin(x) +} + +func asin(x float64) float64 { + if x == 0 { + return x // special case + } + sign := false + if x < 0 { + x = -x + sign = true + } + if x > 1 { + return NaN() // special case + } + + temp := Sqrt(1 - x*x) + if x > 0.7 { + temp = Pi/2 - satan(temp/x) + } else { + temp = satan(x / temp) + } + + if sign { + temp = -temp + } + return temp +} + +// Acos returns the arccosine, in radians, of x. +// +// Special case is: +// Acos(x) = NaN if x < -1 or x > 1 +func Acos(x float64) float64 { + if haveArchAcos { + return archAcos(x) + } + return acos(x) +} + +func acos(x float64) float64 { + return Pi/2 - Asin(x) +} diff --git a/contrib/go/_std_1.18/src/math/asinh.go b/contrib/go/_std_1.18/src/math/asinh.go new file mode 100644 index 0000000000..6dcb241c1f --- /dev/null +++ b/contrib/go/_std_1.18/src/math/asinh.go @@ -0,0 +1,76 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/s_asinh.c +// and came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// +// asinh(x) +// Method : +// Based on +// asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] +// we have +// asinh(x) := x if 1+x*x=1, +// := sign(x)*(log(x)+ln2)) for large |x|, else +// := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else +// := sign(x)*log1p(|x| + x**2/(1 + sqrt(1+x**2))) +// + +// Asinh returns the inverse hyperbolic sine of x. +// +// Special cases are: +// Asinh(±0) = ±0 +// Asinh(±Inf) = ±Inf +// Asinh(NaN) = NaN +func Asinh(x float64) float64 { + if haveArchAsinh { + return archAsinh(x) + } + return asinh(x) +} + +func asinh(x float64) float64 { + const ( + Ln2 = 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF + NearZero = 1.0 / (1 << 28) // 2**-28 + Large = 1 << 28 // 2**28 + ) + // special cases + if IsNaN(x) || IsInf(x, 0) { + return x + } + sign := false + if x < 0 { + x = -x + sign = true + } + var temp float64 + switch { + case x > Large: + temp = Log(x) + Ln2 // |x| > 2**28 + case x > 2: + temp = Log(2*x + 1/(Sqrt(x*x+1)+x)) // 2**28 > |x| > 2.0 + case x < NearZero: + temp = x // |x| < 2**-28 + default: + temp = Log1p(x + x*x/(1+Sqrt(1+x*x))) // 2.0 > |x| > 2**-28 + } + if sign { + temp = -temp + } + return temp +} diff --git a/contrib/go/_std_1.18/src/math/atan.go b/contrib/go/_std_1.18/src/math/atan.go new file mode 100644 index 0000000000..69af860161 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/atan.go @@ -0,0 +1,110 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point arctangent. +*/ + +// The original C code, the long comment, and the constants below were +// from http://netlib.sandia.gov/cephes/cmath/atan.c, available from +// http://www.netlib.org/cephes/cmath.tgz. +// The go code is a version of the original C. +// +// atan.c +// Inverse circular tangent (arctangent) +// +// SYNOPSIS: +// double x, y, atan(); +// y = atan( x ); +// +// DESCRIPTION: +// Returns radian angle between -pi/2 and +pi/2 whose tangent is x. +// +// Range reduction is from three intervals into the interval from zero to 0.66. +// The approximant uses a rational function of degree 4/5 of the form +// x + x**3 P(x)/Q(x). +// +// ACCURACY: +// Relative error: +// arithmetic domain # trials peak rms +// DEC -10, 10 50000 2.4e-17 8.3e-18 +// IEEE -10, 10 10^6 1.8e-16 5.0e-17 +// +// Cephes Math Library Release 2.8: June, 2000 +// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier +// +// The readme file at http://netlib.sandia.gov/cephes/ says: +// Some software in this archive may be from the book _Methods and +// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +// International, 1989) or from the Cephes Mathematical Library, a +// commercial product. In either event, it is copyrighted by the author. +// What you see here may be used freely but it comes with no support or +// guarantee. +// +// The two known misprints in the book are repaired here in the +// source listings for the gamma function and the incomplete beta +// integral. +// +// Stephen L. Moshier +// moshier@na-net.ornl.gov + +// xatan evaluates a series valid in the range [0, 0.66]. +func xatan(x float64) float64 { + const ( + P0 = -8.750608600031904122785e-01 + P1 = -1.615753718733365076637e+01 + P2 = -7.500855792314704667340e+01 + P3 = -1.228866684490136173410e+02 + P4 = -6.485021904942025371773e+01 + Q0 = +2.485846490142306297962e+01 + Q1 = +1.650270098316988542046e+02 + Q2 = +4.328810604912902668951e+02 + Q3 = +4.853903996359136964868e+02 + Q4 = +1.945506571482613964425e+02 + ) + z := x * x + z = z * ((((P0*z+P1)*z+P2)*z+P3)*z + P4) / (((((z+Q0)*z+Q1)*z+Q2)*z+Q3)*z + Q4) + z = x*z + x + return z +} + +// satan reduces its argument (known to be positive) +// to the range [0, 0.66] and calls xatan. +func satan(x float64) float64 { + const ( + Morebits = 6.123233995736765886130e-17 // pi/2 = PIO2 + Morebits + Tan3pio8 = 2.41421356237309504880 // tan(3*pi/8) + ) + if x <= 0.66 { + return xatan(x) + } + if x > Tan3pio8 { + return Pi/2 - xatan(1/x) + Morebits + } + return Pi/4 + xatan((x-1)/(x+1)) + 0.5*Morebits +} + +// Atan returns the arctangent, in radians, of x. +// +// Special cases are: +// Atan(±0) = ±0 +// Atan(±Inf) = ±Pi/2 +func Atan(x float64) float64 { + if haveArchAtan { + return archAtan(x) + } + return atan(x) +} + +func atan(x float64) float64 { + if x == 0 { + return x + } + if x > 0 { + return satan(x) + } + return -satan(-x) +} diff --git a/contrib/go/_std_1.18/src/math/atan2.go b/contrib/go/_std_1.18/src/math/atan2.go new file mode 100644 index 0000000000..11d7e81acd --- /dev/null +++ b/contrib/go/_std_1.18/src/math/atan2.go @@ -0,0 +1,76 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Atan2 returns the arc tangent of y/x, using +// the signs of the two to determine the quadrant +// of the return value. +// +// Special cases are (in order): +// Atan2(y, NaN) = NaN +// Atan2(NaN, x) = NaN +// Atan2(+0, x>=0) = +0 +// Atan2(-0, x>=0) = -0 +// Atan2(+0, x<=-0) = +Pi +// Atan2(-0, x<=-0) = -Pi +// Atan2(y>0, 0) = +Pi/2 +// Atan2(y<0, 0) = -Pi/2 +// Atan2(+Inf, +Inf) = +Pi/4 +// Atan2(-Inf, +Inf) = -Pi/4 +// Atan2(+Inf, -Inf) = 3Pi/4 +// Atan2(-Inf, -Inf) = -3Pi/4 +// Atan2(y, +Inf) = 0 +// Atan2(y>0, -Inf) = +Pi +// Atan2(y<0, -Inf) = -Pi +// Atan2(+Inf, x) = +Pi/2 +// Atan2(-Inf, x) = -Pi/2 +func Atan2(y, x float64) float64 { + if haveArchAtan2 { + return archAtan2(y, x) + } + return atan2(y, x) +} + +func atan2(y, x float64) float64 { + // special cases + switch { + case IsNaN(y) || IsNaN(x): + return NaN() + case y == 0: + if x >= 0 && !Signbit(x) { + return Copysign(0, y) + } + return Copysign(Pi, y) + case x == 0: + return Copysign(Pi/2, y) + case IsInf(x, 0): + if IsInf(x, 1) { + switch { + case IsInf(y, 0): + return Copysign(Pi/4, y) + default: + return Copysign(0, y) + } + } + switch { + case IsInf(y, 0): + return Copysign(3*Pi/4, y) + default: + return Copysign(Pi, y) + } + case IsInf(y, 0): + return Copysign(Pi/2, y) + } + + // Call atan and determine the quadrant. + q := Atan(y / x) + if x < 0 { + if q <= 0 { + return q + Pi + } + return q - Pi + } + return q +} diff --git a/contrib/go/_std_1.18/src/math/atanh.go b/contrib/go/_std_1.18/src/math/atanh.go new file mode 100644 index 0000000000..fe8bd6d8a4 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/atanh.go @@ -0,0 +1,84 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/e_atanh.c +// and came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// +// __ieee754_atanh(x) +// Method : +// 1. Reduce x to positive by atanh(-x) = -atanh(x) +// 2. For x>=0.5 +// 1 2x x +// atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) +// 2 1 - x 1 - x +// +// For x<0.5 +// atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) +// +// Special cases: +// atanh(x) is NaN if |x| > 1 with signal; +// atanh(NaN) is that NaN with no signal; +// atanh(+-1) is +-INF with signal. +// + +// Atanh returns the inverse hyperbolic tangent of x. +// +// Special cases are: +// Atanh(1) = +Inf +// Atanh(±0) = ±0 +// Atanh(-1) = -Inf +// Atanh(x) = NaN if x < -1 or x > 1 +// Atanh(NaN) = NaN +func Atanh(x float64) float64 { + if haveArchAtanh { + return archAtanh(x) + } + return atanh(x) +} + +func atanh(x float64) float64 { + const NearZero = 1.0 / (1 << 28) // 2**-28 + // special cases + switch { + case x < -1 || x > 1 || IsNaN(x): + return NaN() + case x == 1: + return Inf(1) + case x == -1: + return Inf(-1) + } + sign := false + if x < 0 { + x = -x + sign = true + } + var temp float64 + switch { + case x < NearZero: + temp = x + case x < 0.5: + temp = x + x + temp = 0.5 * Log1p(temp+temp*x/(1-x)) + default: + temp = 0.5 * Log1p((x+x)/(1-x)) + } + if sign { + temp = -temp + } + return temp +} diff --git a/contrib/go/_std_1.18/src/math/big/accuracy_string.go b/contrib/go/_std_1.18/src/math/big/accuracy_string.go new file mode 100644 index 0000000000..1501ace00d --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/accuracy_string.go @@ -0,0 +1,17 @@ +// Code generated by "stringer -type=Accuracy"; DO NOT EDIT. + +package big + +import "strconv" + +const _Accuracy_name = "BelowExactAbove" + +var _Accuracy_index = [...]uint8{0, 5, 10, 15} + +func (i Accuracy) String() string { + i -= -1 + if i < 0 || i >= Accuracy(len(_Accuracy_index)-1) { + return "Accuracy(" + strconv.FormatInt(int64(i+-1), 10) + ")" + } + return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]] +} diff --git a/contrib/go/_std_1.18/src/math/big/arith.go b/contrib/go/_std_1.18/src/math/big/arith.go new file mode 100644 index 0000000000..8f55c195d4 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/arith.go @@ -0,0 +1,277 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file provides Go implementations of elementary multi-precision +// arithmetic operations on word vectors. These have the suffix _g. +// These are needed for platforms without assembly implementations of these routines. +// This file also contains elementary operations that can be implemented +// sufficiently efficiently in Go. + +package big + +import "math/bits" + +// A Word represents a single digit of a multi-precision unsigned integer. +type Word uint + +const ( + _S = _W / 8 // word size in bytes + + _W = bits.UintSize // word size in bits + _B = 1 << _W // digit base + _M = _B - 1 // digit mask +) + +// Many of the loops in this file are of the form +// for i := 0; i < len(z) && i < len(x) && i < len(y); i++ +// i < len(z) is the real condition. +// However, checking i < len(x) && i < len(y) as well is faster than +// having the compiler do a bounds check in the body of the loop; +// remarkably it is even faster than hoisting the bounds check +// out of the loop, by doing something like +// _, _ = x[len(z)-1], y[len(z)-1] +// There are other ways to hoist the bounds check out of the loop, +// but the compiler's BCE isn't powerful enough for them (yet?). +// See the discussion in CL 164966. + +// ---------------------------------------------------------------------------- +// Elementary operations on words +// +// These operations are used by the vector operations below. + +// z1<<_W + z0 = x*y +func mulWW_g(x, y Word) (z1, z0 Word) { + hi, lo := bits.Mul(uint(x), uint(y)) + return Word(hi), Word(lo) +} + +// z1<<_W + z0 = x*y + c +func mulAddWWW_g(x, y, c Word) (z1, z0 Word) { + hi, lo := bits.Mul(uint(x), uint(y)) + var cc uint + lo, cc = bits.Add(lo, uint(c), 0) + return Word(hi + cc), Word(lo) +} + +// nlz returns the number of leading zeros in x. +// Wraps bits.LeadingZeros call for convenience. +func nlz(x Word) uint { + return uint(bits.LeadingZeros(uint(x))) +} + +// The resulting carry c is either 0 or 1. +func addVV_g(z, x, y []Word) (c Word) { + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x) && i < len(y); i++ { + zi, cc := bits.Add(uint(x[i]), uint(y[i]), uint(c)) + z[i] = Word(zi) + c = Word(cc) + } + return +} + +// The resulting carry c is either 0 or 1. +func subVV_g(z, x, y []Word) (c Word) { + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x) && i < len(y); i++ { + zi, cc := bits.Sub(uint(x[i]), uint(y[i]), uint(c)) + z[i] = Word(zi) + c = Word(cc) + } + return +} + +// The resulting carry c is either 0 or 1. +func addVW_g(z, x []Word, y Word) (c Word) { + c = y + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x); i++ { + zi, cc := bits.Add(uint(x[i]), uint(c), 0) + z[i] = Word(zi) + c = Word(cc) + } + return +} + +// addVWlarge is addVW, but intended for large z. +// The only difference is that we check on every iteration +// whether we are done with carries, +// and if so, switch to a much faster copy instead. +// This is only a good idea for large z, +// because the overhead of the check and the function call +// outweigh the benefits when z is small. +func addVWlarge(z, x []Word, y Word) (c Word) { + c = y + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x); i++ { + if c == 0 { + copy(z[i:], x[i:]) + return + } + zi, cc := bits.Add(uint(x[i]), uint(c), 0) + z[i] = Word(zi) + c = Word(cc) + } + return +} + +func subVW_g(z, x []Word, y Word) (c Word) { + c = y + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x); i++ { + zi, cc := bits.Sub(uint(x[i]), uint(c), 0) + z[i] = Word(zi) + c = Word(cc) + } + return +} + +// subVWlarge is to subVW as addVWlarge is to addVW. +func subVWlarge(z, x []Word, y Word) (c Word) { + c = y + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x); i++ { + if c == 0 { + copy(z[i:], x[i:]) + return + } + zi, cc := bits.Sub(uint(x[i]), uint(c), 0) + z[i] = Word(zi) + c = Word(cc) + } + return +} + +func shlVU_g(z, x []Word, s uint) (c Word) { + if s == 0 { + copy(z, x) + return + } + if len(z) == 0 { + return + } + s &= _W - 1 // hint to the compiler that shifts by s don't need guard code + ŝ := _W - s + ŝ &= _W - 1 // ditto + c = x[len(z)-1] >> ŝ + for i := len(z) - 1; i > 0; i-- { + z[i] = x[i]<<s | x[i-1]>>ŝ + } + z[0] = x[0] << s + return +} + +func shrVU_g(z, x []Word, s uint) (c Word) { + if s == 0 { + copy(z, x) + return + } + if len(z) == 0 { + return + } + if len(x) != len(z) { + // This is an invariant guaranteed by the caller. + panic("len(x) != len(z)") + } + s &= _W - 1 // hint to the compiler that shifts by s don't need guard code + ŝ := _W - s + ŝ &= _W - 1 // ditto + c = x[0] << ŝ + for i := 1; i < len(z); i++ { + z[i-1] = x[i-1]>>s | x[i]<<ŝ + } + z[len(z)-1] = x[len(z)-1] >> s + return +} + +func mulAddVWW_g(z, x []Word, y, r Word) (c Word) { + c = r + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x); i++ { + c, z[i] = mulAddWWW_g(x[i], y, c) + } + return +} + +func addMulVVW_g(z, x []Word, y Word) (c Word) { + // The comment near the top of this file discusses this for loop condition. + for i := 0; i < len(z) && i < len(x); i++ { + z1, z0 := mulAddWWW_g(x[i], y, z[i]) + lo, cc := bits.Add(uint(z0), uint(c), 0) + c, z[i] = Word(cc), Word(lo) + c += z1 + } + return +} + +// q = ( x1 << _W + x0 - r)/y. m = floor(( _B^2 - 1 ) / d - _B). Requiring x1<y. +// An approximate reciprocal with a reference to "Improved Division by Invariant Integers +// (IEEE Transactions on Computers, 11 Jun. 2010)" +func divWW(x1, x0, y, m Word) (q, r Word) { + s := nlz(y) + if s != 0 { + x1 = x1<<s | x0>>(_W-s) + x0 <<= s + y <<= s + } + d := uint(y) + // We know that + // m = ⎣(B^2-1)/d⎦-B + // ⎣(B^2-1)/d⎦ = m+B + // (B^2-1)/d = m+B+delta1 0 <= delta1 <= (d-1)/d + // B^2/d = m+B+delta2 0 <= delta2 <= 1 + // The quotient we're trying to compute is + // quotient = ⎣(x1*B+x0)/d⎦ + // = ⎣(x1*B*(B^2/d)+x0*(B^2/d))/B^2⎦ + // = ⎣(x1*B*(m+B+delta2)+x0*(m+B+delta2))/B^2⎦ + // = ⎣(x1*m+x1*B+x0)/B + x0*m/B^2 + delta2*(x1*B+x0)/B^2⎦ + // The latter two terms of this three-term sum are between 0 and 1. + // So we can compute just the first term, and we will be low by at most 2. + t1, t0 := bits.Mul(uint(m), uint(x1)) + _, c := bits.Add(t0, uint(x0), 0) + t1, _ = bits.Add(t1, uint(x1), c) + // The quotient is either t1, t1+1, or t1+2. + // We'll try t1 and adjust if needed. + qq := t1 + // compute remainder r=x-d*q. + dq1, dq0 := bits.Mul(d, qq) + r0, b := bits.Sub(uint(x0), dq0, 0) + r1, _ := bits.Sub(uint(x1), dq1, b) + // The remainder we just computed is bounded above by B+d: + // r = x1*B + x0 - d*q. + // = x1*B + x0 - d*⎣(x1*m+x1*B+x0)/B⎦ + // = x1*B + x0 - d*((x1*m+x1*B+x0)/B-alpha) 0 <= alpha < 1 + // = x1*B + x0 - x1*d/B*m - x1*d - x0*d/B + d*alpha + // = x1*B + x0 - x1*d/B*⎣(B^2-1)/d-B⎦ - x1*d - x0*d/B + d*alpha + // = x1*B + x0 - x1*d/B*⎣(B^2-1)/d-B⎦ - x1*d - x0*d/B + d*alpha + // = x1*B + x0 - x1*d/B*((B^2-1)/d-B-beta) - x1*d - x0*d/B + d*alpha 0 <= beta < 1 + // = x1*B + x0 - x1*B + x1/B + x1*d + x1*d/B*beta - x1*d - x0*d/B + d*alpha + // = x0 + x1/B + x1*d/B*beta - x0*d/B + d*alpha + // = x0*(1-d/B) + x1*(1+d*beta)/B + d*alpha + // < B*(1-d/B) + d*B/B + d because x0<B (and 1-d/B>0), x1<d, 1+d*beta<=B, alpha<1 + // = B - d + d + d + // = B+d + // So r1 can only be 0 or 1. If r1 is 1, then we know q was too small. + // Add 1 to q and subtract d from r. That guarantees that r is <B, so + // we no longer need to keep track of r1. + if r1 != 0 { + qq++ + r0 -= d + } + // If the remainder is still too large, increment q one more time. + if r0 >= d { + qq++ + r0 -= d + } + return Word(qq), Word(r0 >> s) +} + +// reciprocalWord return the reciprocal of the divisor. rec = floor(( _B^2 - 1 ) / u - _B). u = d1 << nlz(d1). +func reciprocalWord(d1 Word) Word { + u := uint(d1 << nlz(d1)) + x1 := ^u + x0 := uint(_M) + rec, _ := bits.Div(x1, x0, u) // (_B^2-1)/U-_B = (_B*(_M-C)+_M)/U + return Word(rec) +} diff --git a/contrib/go/_std_1.18/src/math/big/arith_amd64.go b/contrib/go/_std_1.18/src/math/big/arith_amd64.go new file mode 100644 index 0000000000..89108fe149 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/arith_amd64.go @@ -0,0 +1,12 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !math_big_pure_go +// +build !math_big_pure_go + +package big + +import "internal/cpu" + +var support_adx = cpu.X86.HasADX && cpu.X86.HasBMI2 diff --git a/contrib/go/_std_1.18/src/math/big/arith_amd64.s b/contrib/go/_std_1.18/src/math/big/arith_amd64.s new file mode 100644 index 0000000000..5c72a27d8d --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/arith_amd64.s @@ -0,0 +1,526 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !math_big_pure_go +// +build !math_big_pure_go + +#include "textflag.h" + +// This file provides fast assembly versions for the elementary +// arithmetic operations on vectors implemented in arith.go. + +// func mulWW(x, y Word) (z1, z0 Word) +TEXT ·mulWW(SB),NOSPLIT,$0 + MOVQ x+0(FP), AX + MULQ y+8(FP) + MOVQ DX, z1+16(FP) + MOVQ AX, z0+24(FP) + RET + + + +// The carry bit is saved with SBBQ Rx, Rx: if the carry was set, Rx is -1, otherwise it is 0. +// It is restored with ADDQ Rx, Rx: if Rx was -1 the carry is set, otherwise it is cleared. +// This is faster than using rotate instructions. + +// func addVV(z, x, y []Word) (c Word) +TEXT ·addVV(SB),NOSPLIT,$0 + MOVQ z_len+8(FP), DI + MOVQ x+24(FP), R8 + MOVQ y+48(FP), R9 + MOVQ z+0(FP), R10 + + MOVQ $0, CX // c = 0 + MOVQ $0, SI // i = 0 + + // s/JL/JMP/ below to disable the unrolled loop + SUBQ $4, DI // n -= 4 + JL V1 // if n < 0 goto V1 + +U1: // n >= 0 + // regular loop body unrolled 4x + ADDQ CX, CX // restore CF + MOVQ 0(R8)(SI*8), R11 + MOVQ 8(R8)(SI*8), R12 + MOVQ 16(R8)(SI*8), R13 + MOVQ 24(R8)(SI*8), R14 + ADCQ 0(R9)(SI*8), R11 + ADCQ 8(R9)(SI*8), R12 + ADCQ 16(R9)(SI*8), R13 + ADCQ 24(R9)(SI*8), R14 + MOVQ R11, 0(R10)(SI*8) + MOVQ R12, 8(R10)(SI*8) + MOVQ R13, 16(R10)(SI*8) + MOVQ R14, 24(R10)(SI*8) + SBBQ CX, CX // save CF + + ADDQ $4, SI // i += 4 + SUBQ $4, DI // n -= 4 + JGE U1 // if n >= 0 goto U1 + +V1: ADDQ $4, DI // n += 4 + JLE E1 // if n <= 0 goto E1 + +L1: // n > 0 + ADDQ CX, CX // restore CF + MOVQ 0(R8)(SI*8), R11 + ADCQ 0(R9)(SI*8), R11 + MOVQ R11, 0(R10)(SI*8) + SBBQ CX, CX // save CF + + ADDQ $1, SI // i++ + SUBQ $1, DI // n-- + JG L1 // if n > 0 goto L1 + +E1: NEGQ CX + MOVQ CX, c+72(FP) // return c + RET + + +// func subVV(z, x, y []Word) (c Word) +// (same as addVV except for SBBQ instead of ADCQ and label names) +TEXT ·subVV(SB),NOSPLIT,$0 + MOVQ z_len+8(FP), DI + MOVQ x+24(FP), R8 + MOVQ y+48(FP), R9 + MOVQ z+0(FP), R10 + + MOVQ $0, CX // c = 0 + MOVQ $0, SI // i = 0 + + // s/JL/JMP/ below to disable the unrolled loop + SUBQ $4, DI // n -= 4 + JL V2 // if n < 0 goto V2 + +U2: // n >= 0 + // regular loop body unrolled 4x + ADDQ CX, CX // restore CF + MOVQ 0(R8)(SI*8), R11 + MOVQ 8(R8)(SI*8), R12 + MOVQ 16(R8)(SI*8), R13 + MOVQ 24(R8)(SI*8), R14 + SBBQ 0(R9)(SI*8), R11 + SBBQ 8(R9)(SI*8), R12 + SBBQ 16(R9)(SI*8), R13 + SBBQ 24(R9)(SI*8), R14 + MOVQ R11, 0(R10)(SI*8) + MOVQ R12, 8(R10)(SI*8) + MOVQ R13, 16(R10)(SI*8) + MOVQ R14, 24(R10)(SI*8) + SBBQ CX, CX // save CF + + ADDQ $4, SI // i += 4 + SUBQ $4, DI // n -= 4 + JGE U2 // if n >= 0 goto U2 + +V2: ADDQ $4, DI // n += 4 + JLE E2 // if n <= 0 goto E2 + +L2: // n > 0 + ADDQ CX, CX // restore CF + MOVQ 0(R8)(SI*8), R11 + SBBQ 0(R9)(SI*8), R11 + MOVQ R11, 0(R10)(SI*8) + SBBQ CX, CX // save CF + + ADDQ $1, SI // i++ + SUBQ $1, DI // n-- + JG L2 // if n > 0 goto L2 + +E2: NEGQ CX + MOVQ CX, c+72(FP) // return c + RET + + +// func addVW(z, x []Word, y Word) (c Word) +TEXT ·addVW(SB),NOSPLIT,$0 + MOVQ z_len+8(FP), DI + CMPQ DI, $32 + JG large + MOVQ x+24(FP), R8 + MOVQ y+48(FP), CX // c = y + MOVQ z+0(FP), R10 + + MOVQ $0, SI // i = 0 + + // s/JL/JMP/ below to disable the unrolled loop + SUBQ $4, DI // n -= 4 + JL V3 // if n < 4 goto V3 + +U3: // n >= 0 + // regular loop body unrolled 4x + MOVQ 0(R8)(SI*8), R11 + MOVQ 8(R8)(SI*8), R12 + MOVQ 16(R8)(SI*8), R13 + MOVQ 24(R8)(SI*8), R14 + ADDQ CX, R11 + ADCQ $0, R12 + ADCQ $0, R13 + ADCQ $0, R14 + SBBQ CX, CX // save CF + NEGQ CX + MOVQ R11, 0(R10)(SI*8) + MOVQ R12, 8(R10)(SI*8) + MOVQ R13, 16(R10)(SI*8) + MOVQ R14, 24(R10)(SI*8) + + ADDQ $4, SI // i += 4 + SUBQ $4, DI // n -= 4 + JGE U3 // if n >= 0 goto U3 + +V3: ADDQ $4, DI // n += 4 + JLE E3 // if n <= 0 goto E3 + +L3: // n > 0 + ADDQ 0(R8)(SI*8), CX + MOVQ CX, 0(R10)(SI*8) + SBBQ CX, CX // save CF + NEGQ CX + + ADDQ $1, SI // i++ + SUBQ $1, DI // n-- + JG L3 // if n > 0 goto L3 + +E3: MOVQ CX, c+56(FP) // return c + RET +large: + JMP ·addVWlarge(SB) + + +// func subVW(z, x []Word, y Word) (c Word) +// (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names) +TEXT ·subVW(SB),NOSPLIT,$0 + MOVQ z_len+8(FP), DI + CMPQ DI, $32 + JG large + MOVQ x+24(FP), R8 + MOVQ y+48(FP), CX // c = y + MOVQ z+0(FP), R10 + + MOVQ $0, SI // i = 0 + + // s/JL/JMP/ below to disable the unrolled loop + SUBQ $4, DI // n -= 4 + JL V4 // if n < 4 goto V4 + +U4: // n >= 0 + // regular loop body unrolled 4x + MOVQ 0(R8)(SI*8), R11 + MOVQ 8(R8)(SI*8), R12 + MOVQ 16(R8)(SI*8), R13 + MOVQ 24(R8)(SI*8), R14 + SUBQ CX, R11 + SBBQ $0, R12 + SBBQ $0, R13 + SBBQ $0, R14 + SBBQ CX, CX // save CF + NEGQ CX + MOVQ R11, 0(R10)(SI*8) + MOVQ R12, 8(R10)(SI*8) + MOVQ R13, 16(R10)(SI*8) + MOVQ R14, 24(R10)(SI*8) + + ADDQ $4, SI // i += 4 + SUBQ $4, DI // n -= 4 + JGE U4 // if n >= 0 goto U4 + +V4: ADDQ $4, DI // n += 4 + JLE E4 // if n <= 0 goto E4 + +L4: // n > 0 + MOVQ 0(R8)(SI*8), R11 + SUBQ CX, R11 + MOVQ R11, 0(R10)(SI*8) + SBBQ CX, CX // save CF + NEGQ CX + + ADDQ $1, SI // i++ + SUBQ $1, DI // n-- + JG L4 // if n > 0 goto L4 + +E4: MOVQ CX, c+56(FP) // return c + RET +large: + JMP ·subVWlarge(SB) + + +// func shlVU(z, x []Word, s uint) (c Word) +TEXT ·shlVU(SB),NOSPLIT,$0 + MOVQ z_len+8(FP), BX // i = z + SUBQ $1, BX // i-- + JL X8b // i < 0 (n <= 0) + + // n > 0 + MOVQ z+0(FP), R10 + MOVQ x+24(FP), R8 + MOVQ s+48(FP), CX + MOVQ (R8)(BX*8), AX // w1 = x[n-1] + MOVQ $0, DX + SHLQ CX, AX, DX // w1>>ŝ + MOVQ DX, c+56(FP) + + CMPQ BX, $0 + JLE X8a // i <= 0 + + // i > 0 +L8: MOVQ AX, DX // w = w1 + MOVQ -8(R8)(BX*8), AX // w1 = x[i-1] + SHLQ CX, AX, DX // w<<s | w1>>ŝ + MOVQ DX, (R10)(BX*8) // z[i] = w<<s | w1>>ŝ + SUBQ $1, BX // i-- + JG L8 // i > 0 + + // i <= 0 +X8a: SHLQ CX, AX // w1<<s + MOVQ AX, (R10) // z[0] = w1<<s + RET + +X8b: MOVQ $0, c+56(FP) + RET + + +// func shrVU(z, x []Word, s uint) (c Word) +TEXT ·shrVU(SB),NOSPLIT,$0 + MOVQ z_len+8(FP), R11 + SUBQ $1, R11 // n-- + JL X9b // n < 0 (n <= 0) + + // n > 0 + MOVQ z+0(FP), R10 + MOVQ x+24(FP), R8 + MOVQ s+48(FP), CX + MOVQ (R8), AX // w1 = x[0] + MOVQ $0, DX + SHRQ CX, AX, DX // w1<<ŝ + MOVQ DX, c+56(FP) + + MOVQ $0, BX // i = 0 + JMP E9 + + // i < n-1 +L9: MOVQ AX, DX // w = w1 + MOVQ 8(R8)(BX*8), AX // w1 = x[i+1] + SHRQ CX, AX, DX // w>>s | w1<<ŝ + MOVQ DX, (R10)(BX*8) // z[i] = w>>s | w1<<ŝ + ADDQ $1, BX // i++ + +E9: CMPQ BX, R11 + JL L9 // i < n-1 + + // i >= n-1 +X9a: SHRQ CX, AX // w1>>s + MOVQ AX, (R10)(R11*8) // z[n-1] = w1>>s + RET + +X9b: MOVQ $0, c+56(FP) + RET + + +// func mulAddVWW(z, x []Word, y, r Word) (c Word) +TEXT ·mulAddVWW(SB),NOSPLIT,$0 + MOVQ z+0(FP), R10 + MOVQ x+24(FP), R8 + MOVQ y+48(FP), R9 + MOVQ r+56(FP), CX // c = r + MOVQ z_len+8(FP), R11 + MOVQ $0, BX // i = 0 + + CMPQ R11, $4 + JL E5 + +U5: // i+4 <= n + // regular loop body unrolled 4x + MOVQ (0*8)(R8)(BX*8), AX + MULQ R9 + ADDQ CX, AX + ADCQ $0, DX + MOVQ AX, (0*8)(R10)(BX*8) + MOVQ DX, CX + MOVQ (1*8)(R8)(BX*8), AX + MULQ R9 + ADDQ CX, AX + ADCQ $0, DX + MOVQ AX, (1*8)(R10)(BX*8) + MOVQ DX, CX + MOVQ (2*8)(R8)(BX*8), AX + MULQ R9 + ADDQ CX, AX + ADCQ $0, DX + MOVQ AX, (2*8)(R10)(BX*8) + MOVQ DX, CX + MOVQ (3*8)(R8)(BX*8), AX + MULQ R9 + ADDQ CX, AX + ADCQ $0, DX + MOVQ AX, (3*8)(R10)(BX*8) + MOVQ DX, CX + ADDQ $4, BX // i += 4 + + LEAQ 4(BX), DX + CMPQ DX, R11 + JLE U5 + JMP E5 + +L5: MOVQ (R8)(BX*8), AX + MULQ R9 + ADDQ CX, AX + ADCQ $0, DX + MOVQ AX, (R10)(BX*8) + MOVQ DX, CX + ADDQ $1, BX // i++ + +E5: CMPQ BX, R11 // i < n + JL L5 + + MOVQ CX, c+64(FP) + RET + + +// func addMulVVW(z, x []Word, y Word) (c Word) +TEXT ·addMulVVW(SB),NOSPLIT,$0 + CMPB ·support_adx(SB), $1 + JEQ adx + MOVQ z+0(FP), R10 + MOVQ x+24(FP), R8 + MOVQ y+48(FP), R9 + MOVQ z_len+8(FP), R11 + MOVQ $0, BX // i = 0 + MOVQ $0, CX // c = 0 + MOVQ R11, R12 + ANDQ $-2, R12 + CMPQ R11, $2 + JAE A6 + JMP E6 + +A6: + MOVQ (R8)(BX*8), AX + MULQ R9 + ADDQ (R10)(BX*8), AX + ADCQ $0, DX + ADDQ CX, AX + ADCQ $0, DX + MOVQ DX, CX + MOVQ AX, (R10)(BX*8) + + MOVQ (8)(R8)(BX*8), AX + MULQ R9 + ADDQ (8)(R10)(BX*8), AX + ADCQ $0, DX + ADDQ CX, AX + ADCQ $0, DX + MOVQ DX, CX + MOVQ AX, (8)(R10)(BX*8) + + ADDQ $2, BX + CMPQ BX, R12 + JL A6 + JMP E6 + +L6: MOVQ (R8)(BX*8), AX + MULQ R9 + ADDQ CX, AX + ADCQ $0, DX + ADDQ AX, (R10)(BX*8) + ADCQ $0, DX + MOVQ DX, CX + ADDQ $1, BX // i++ + +E6: CMPQ BX, R11 // i < n + JL L6 + + MOVQ CX, c+56(FP) + RET + +adx: + MOVQ z_len+8(FP), R11 + MOVQ z+0(FP), R10 + MOVQ x+24(FP), R8 + MOVQ y+48(FP), DX + MOVQ $0, BX // i = 0 + MOVQ $0, CX // carry + CMPQ R11, $8 + JAE adx_loop_header + CMPQ BX, R11 + JL adx_short + MOVQ CX, c+56(FP) + RET + +adx_loop_header: + MOVQ R11, R13 + ANDQ $-8, R13 +adx_loop: + XORQ R9, R9 // unset flags + MULXQ (R8), SI, DI + ADCXQ CX,SI + ADOXQ (R10), SI + MOVQ SI,(R10) + + MULXQ 8(R8), AX, CX + ADCXQ DI, AX + ADOXQ 8(R10), AX + MOVQ AX, 8(R10) + + MULXQ 16(R8), SI, DI + ADCXQ CX, SI + ADOXQ 16(R10), SI + MOVQ SI, 16(R10) + + MULXQ 24(R8), AX, CX + ADCXQ DI, AX + ADOXQ 24(R10), AX + MOVQ AX, 24(R10) + + MULXQ 32(R8), SI, DI + ADCXQ CX, SI + ADOXQ 32(R10), SI + MOVQ SI, 32(R10) + + MULXQ 40(R8), AX, CX + ADCXQ DI, AX + ADOXQ 40(R10), AX + MOVQ AX, 40(R10) + + MULXQ 48(R8), SI, DI + ADCXQ CX, SI + ADOXQ 48(R10), SI + MOVQ SI, 48(R10) + + MULXQ 56(R8), AX, CX + ADCXQ DI, AX + ADOXQ 56(R10), AX + MOVQ AX, 56(R10) + + ADCXQ R9, CX + ADOXQ R9, CX + + ADDQ $64, R8 + ADDQ $64, R10 + ADDQ $8, BX + + CMPQ BX, R13 + JL adx_loop + MOVQ z+0(FP), R10 + MOVQ x+24(FP), R8 + CMPQ BX, R11 + JL adx_short + MOVQ CX, c+56(FP) + RET + +adx_short: + MULXQ (R8)(BX*8), SI, DI + ADDQ CX, SI + ADCQ $0, DI + ADDQ SI, (R10)(BX*8) + ADCQ $0, DI + MOVQ DI, CX + ADDQ $1, BX // i++ + + CMPQ BX, R11 + JL adx_short + + MOVQ CX, c+56(FP) + RET + + + diff --git a/contrib/go/_std_1.18/src/math/big/arith_decl.go b/contrib/go/_std_1.18/src/math/big/arith_decl.go new file mode 100644 index 0000000000..eea3d6b325 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/arith_decl.go @@ -0,0 +1,19 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !math_big_pure_go +// +build !math_big_pure_go + +package big + +// implemented in arith_$GOARCH.s +func mulWW(x, y Word) (z1, z0 Word) +func addVV(z, x, y []Word) (c Word) +func subVV(z, x, y []Word) (c Word) +func addVW(z, x []Word, y Word) (c Word) +func subVW(z, x []Word, y Word) (c Word) +func shlVU(z, x []Word, s uint) (c Word) +func shrVU(z, x []Word, s uint) (c Word) +func mulAddVWW(z, x []Word, y, r Word) (c Word) +func addMulVVW(z, x []Word, y Word) (c Word) diff --git a/contrib/go/_std_1.18/src/math/big/decimal.go b/contrib/go/_std_1.18/src/math/big/decimal.go new file mode 100644 index 0000000000..716f03bfa4 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/decimal.go @@ -0,0 +1,270 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements multi-precision decimal numbers. +// The implementation is for float to decimal conversion only; +// not general purpose use. +// The only operations are precise conversion from binary to +// decimal and rounding. +// +// The key observation and some code (shr) is borrowed from +// strconv/decimal.go: conversion of binary fractional values can be done +// precisely in multi-precision decimal because 2 divides 10 (required for +// >> of mantissa); but conversion of decimal floating-point values cannot +// be done precisely in binary representation. +// +// In contrast to strconv/decimal.go, only right shift is implemented in +// decimal format - left shift can be done precisely in binary format. + +package big + +// A decimal represents an unsigned floating-point number in decimal representation. +// The value of a non-zero decimal d is d.mant * 10**d.exp with 0.1 <= d.mant < 1, +// with the most-significant mantissa digit at index 0. For the zero decimal, the +// mantissa length and exponent are 0. +// The zero value for decimal represents a ready-to-use 0.0. +type decimal struct { + mant []byte // mantissa ASCII digits, big-endian + exp int // exponent +} + +// at returns the i'th mantissa digit, starting with the most significant digit at 0. +func (d *decimal) at(i int) byte { + if 0 <= i && i < len(d.mant) { + return d.mant[i] + } + return '0' +} + +// Maximum shift amount that can be done in one pass without overflow. +// A Word has _W bits and (1<<maxShift - 1)*10 + 9 must fit into Word. +const maxShift = _W - 4 + +// TODO(gri) Since we know the desired decimal precision when converting +// a floating-point number, we may be able to limit the number of decimal +// digits that need to be computed by init by providing an additional +// precision argument and keeping track of when a number was truncated early +// (equivalent of "sticky bit" in binary rounding). + +// TODO(gri) Along the same lines, enforce some limit to shift magnitudes +// to avoid "infinitely" long running conversions (until we run out of space). + +// Init initializes x to the decimal representation of m << shift (for +// shift >= 0), or m >> -shift (for shift < 0). +func (x *decimal) init(m nat, shift int) { + // special case 0 + if len(m) == 0 { + x.mant = x.mant[:0] + x.exp = 0 + return + } + + // Optimization: If we need to shift right, first remove any trailing + // zero bits from m to reduce shift amount that needs to be done in + // decimal format (since that is likely slower). + if shift < 0 { + ntz := m.trailingZeroBits() + s := uint(-shift) + if s >= ntz { + s = ntz // shift at most ntz bits + } + m = nat(nil).shr(m, s) + shift += int(s) + } + + // Do any shift left in binary representation. + if shift > 0 { + m = nat(nil).shl(m, uint(shift)) + shift = 0 + } + + // Convert mantissa into decimal representation. + s := m.utoa(10) + n := len(s) + x.exp = n + // Trim trailing zeros; instead the exponent is tracking + // the decimal point independent of the number of digits. + for n > 0 && s[n-1] == '0' { + n-- + } + x.mant = append(x.mant[:0], s[:n]...) + + // Do any (remaining) shift right in decimal representation. + if shift < 0 { + for shift < -maxShift { + shr(x, maxShift) + shift += maxShift + } + shr(x, uint(-shift)) + } +} + +// shr implements x >> s, for s <= maxShift. +func shr(x *decimal, s uint) { + // Division by 1<<s using shift-and-subtract algorithm. + + // pick up enough leading digits to cover first shift + r := 0 // read index + var n Word + for n>>s == 0 && r < len(x.mant) { + ch := Word(x.mant[r]) + r++ + n = n*10 + ch - '0' + } + if n == 0 { + // x == 0; shouldn't get here, but handle anyway + x.mant = x.mant[:0] + return + } + for n>>s == 0 { + r++ + n *= 10 + } + x.exp += 1 - r + + // read a digit, write a digit + w := 0 // write index + mask := Word(1)<<s - 1 + for r < len(x.mant) { + ch := Word(x.mant[r]) + r++ + d := n >> s + n &= mask // n -= d << s + x.mant[w] = byte(d + '0') + w++ + n = n*10 + ch - '0' + } + + // write extra digits that still fit + for n > 0 && w < len(x.mant) { + d := n >> s + n &= mask + x.mant[w] = byte(d + '0') + w++ + n = n * 10 + } + x.mant = x.mant[:w] // the number may be shorter (e.g. 1024 >> 10) + + // append additional digits that didn't fit + for n > 0 { + d := n >> s + n &= mask + x.mant = append(x.mant, byte(d+'0')) + n = n * 10 + } + + trim(x) +} + +func (x *decimal) String() string { + if len(x.mant) == 0 { + return "0" + } + + var buf []byte + switch { + case x.exp <= 0: + // 0.00ddd + buf = make([]byte, 0, 2+(-x.exp)+len(x.mant)) + buf = append(buf, "0."...) + buf = appendZeros(buf, -x.exp) + buf = append(buf, x.mant...) + + case /* 0 < */ x.exp < len(x.mant): + // dd.ddd + buf = make([]byte, 0, 1+len(x.mant)) + buf = append(buf, x.mant[:x.exp]...) + buf = append(buf, '.') + buf = append(buf, x.mant[x.exp:]...) + + default: // len(x.mant) <= x.exp + // ddd00 + buf = make([]byte, 0, x.exp) + buf = append(buf, x.mant...) + buf = appendZeros(buf, x.exp-len(x.mant)) + } + + return string(buf) +} + +// appendZeros appends n 0 digits to buf and returns buf. +func appendZeros(buf []byte, n int) []byte { + for ; n > 0; n-- { + buf = append(buf, '0') + } + return buf +} + +// shouldRoundUp reports if x should be rounded up +// if shortened to n digits. n must be a valid index +// for x.mant. +func shouldRoundUp(x *decimal, n int) bool { + if x.mant[n] == '5' && n+1 == len(x.mant) { + // exactly halfway - round to even + return n > 0 && (x.mant[n-1]-'0')&1 != 0 + } + // not halfway - digit tells all (x.mant has no trailing zeros) + return x.mant[n] >= '5' +} + +// round sets x to (at most) n mantissa digits by rounding it +// to the nearest even value with n (or fever) mantissa digits. +// If n < 0, x remains unchanged. +func (x *decimal) round(n int) { + if n < 0 || n >= len(x.mant) { + return // nothing to do + } + + if shouldRoundUp(x, n) { + x.roundUp(n) + } else { + x.roundDown(n) + } +} + +func (x *decimal) roundUp(n int) { + if n < 0 || n >= len(x.mant) { + return // nothing to do + } + // 0 <= n < len(x.mant) + + // find first digit < '9' + for n > 0 && x.mant[n-1] >= '9' { + n-- + } + + if n == 0 { + // all digits are '9's => round up to '1' and update exponent + x.mant[0] = '1' // ok since len(x.mant) > n + x.mant = x.mant[:1] + x.exp++ + return + } + + // n > 0 && x.mant[n-1] < '9' + x.mant[n-1]++ + x.mant = x.mant[:n] + // x already trimmed +} + +func (x *decimal) roundDown(n int) { + if n < 0 || n >= len(x.mant) { + return // nothing to do + } + x.mant = x.mant[:n] + trim(x) +} + +// trim cuts off any trailing zeros from x's mantissa; +// they are meaningless for the value of x. +func trim(x *decimal) { + i := len(x.mant) + for i > 0 && x.mant[i-1] == '0' { + i-- + } + x.mant = x.mant[:i] + if i == 0 { + x.exp = 0 + } +} diff --git a/contrib/go/_std_1.18/src/math/big/doc.go b/contrib/go/_std_1.18/src/math/big/doc.go new file mode 100644 index 0000000000..65ed019b74 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/doc.go @@ -0,0 +1,99 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package big implements arbitrary-precision arithmetic (big numbers). +The following numeric types are supported: + + Int signed integers + Rat rational numbers + Float floating-point numbers + +The zero value for an Int, Rat, or Float correspond to 0. Thus, new +values can be declared in the usual ways and denote 0 without further +initialization: + + var x Int // &x is an *Int of value 0 + var r = &Rat{} // r is a *Rat of value 0 + y := new(Float) // y is a *Float of value 0 + +Alternatively, new values can be allocated and initialized with factory +functions of the form: + + func NewT(v V) *T + +For instance, NewInt(x) returns an *Int set to the value of the int64 +argument x, NewRat(a, b) returns a *Rat set to the fraction a/b where +a and b are int64 values, and NewFloat(f) returns a *Float initialized +to the float64 argument f. More flexibility is provided with explicit +setters, for instance: + + var z1 Int + z1.SetUint64(123) // z1 := 123 + z2 := new(Rat).SetFloat64(1.25) // z2 := 5/4 + z3 := new(Float).SetInt(z1) // z3 := 123.0 + +Setters, numeric operations and predicates are represented as methods of +the form: + + func (z *T) SetV(v V) *T // z = v + func (z *T) Unary(x *T) *T // z = unary x + func (z *T) Binary(x, y *T) *T // z = x binary y + func (x *T) Pred() P // p = pred(x) + +with T one of Int, Rat, or Float. For unary and binary operations, the +result is the receiver (usually named z in that case; see below); if it +is one of the operands x or y it may be safely overwritten (and its memory +reused). + +Arithmetic expressions are typically written as a sequence of individual +method calls, with each call corresponding to an operation. The receiver +denotes the result and the method arguments are the operation's operands. +For instance, given three *Int values a, b and c, the invocation + + c.Add(a, b) + +computes the sum a + b and stores the result in c, overwriting whatever +value was held in c before. Unless specified otherwise, operations permit +aliasing of parameters, so it is perfectly ok to write + + sum.Add(sum, x) + +to accumulate values x in a sum. + +(By always passing in a result value via the receiver, memory use can be +much better controlled. Instead of having to allocate new memory for each +result, an operation can reuse the space allocated for the result value, +and overwrite that value with the new result in the process.) + +Notational convention: Incoming method parameters (including the receiver) +are named consistently in the API to clarify their use. Incoming operands +are usually named x, y, a, b, and so on, but never z. A parameter specifying +the result is named z (typically the receiver). + +For instance, the arguments for (*Int).Add are named x and y, and because +the receiver specifies the result destination, it is called z: + + func (z *Int) Add(x, y *Int) *Int + +Methods of this form typically return the incoming receiver as well, to +enable simple call chaining. + +Methods which don't require a result value to be passed in (for instance, +Int.Sign), simply return the result. In this case, the receiver is typically +the first operand, named x: + + func (x *Int) Sign() int + +Various methods support conversions between strings and corresponding +numeric values, and vice versa: *Int, *Rat, and *Float values implement +the Stringer interface for a (default) string representation of the value, +but also provide SetString methods to initialize a value from a string in +a variety of supported formats (see the respective SetString documentation). + +Finally, *Int, *Rat, and *Float satisfy the fmt package's Scanner interface +for scanning and (except for *Rat) the Formatter interface for formatted +printing. +*/ +package big diff --git a/contrib/go/_std_1.18/src/math/big/float.go b/contrib/go/_std_1.18/src/math/big/float.go new file mode 100644 index 0000000000..a8c91a6e54 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/float.go @@ -0,0 +1,1732 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements multi-precision floating-point numbers. +// Like in the GNU MPFR library (https://www.mpfr.org/), operands +// can be of mixed precision. Unlike MPFR, the rounding mode is +// not specified with each operation, but with each operand. The +// rounding mode of the result operand determines the rounding +// mode of an operation. This is a from-scratch implementation. + +package big + +import ( + "fmt" + "math" + "math/bits" +) + +const debugFloat = false // enable for debugging + +// A nonzero finite Float represents a multi-precision floating point number +// +// sign × mantissa × 2**exponent +// +// with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp. +// A Float may also be zero (+0, -0) or infinite (+Inf, -Inf). +// All Floats are ordered, and the ordering of two Floats x and y +// is defined by x.Cmp(y). +// +// Each Float value also has a precision, rounding mode, and accuracy. +// The precision is the maximum number of mantissa bits available to +// represent the value. The rounding mode specifies how a result should +// be rounded to fit into the mantissa bits, and accuracy describes the +// rounding error with respect to the exact result. +// +// Unless specified otherwise, all operations (including setters) that +// specify a *Float variable for the result (usually via the receiver +// with the exception of MantExp), round the numeric result according +// to the precision and rounding mode of the result variable. +// +// If the provided result precision is 0 (see below), it is set to the +// precision of the argument with the largest precision value before any +// rounding takes place, and the rounding mode remains unchanged. Thus, +// uninitialized Floats provided as result arguments will have their +// precision set to a reasonable value determined by the operands, and +// their mode is the zero value for RoundingMode (ToNearestEven). +// +// By setting the desired precision to 24 or 53 and using matching rounding +// mode (typically ToNearestEven), Float operations produce the same results +// as the corresponding float32 or float64 IEEE-754 arithmetic for operands +// that correspond to normal (i.e., not denormal) float32 or float64 numbers. +// Exponent underflow and overflow lead to a 0 or an Infinity for different +// values than IEEE-754 because Float exponents have a much larger range. +// +// The zero (uninitialized) value for a Float is ready to use and represents +// the number +0.0 exactly, with precision 0 and rounding mode ToNearestEven. +// +// Operations always take pointer arguments (*Float) rather +// than Float values, and each unique Float value requires +// its own unique *Float pointer. To "copy" a Float value, +// an existing (or newly allocated) Float must be set to +// a new value using the Float.Set method; shallow copies +// of Floats are not supported and may lead to errors. +type Float struct { + prec uint32 + mode RoundingMode + acc Accuracy + form form + neg bool + mant nat + exp int32 +} + +// An ErrNaN panic is raised by a Float operation that would lead to +// a NaN under IEEE-754 rules. An ErrNaN implements the error interface. +type ErrNaN struct { + msg string +} + +func (err ErrNaN) Error() string { + return err.msg +} + +// NewFloat allocates and returns a new Float set to x, +// with precision 53 and rounding mode ToNearestEven. +// NewFloat panics with ErrNaN if x is a NaN. +func NewFloat(x float64) *Float { + if math.IsNaN(x) { + panic(ErrNaN{"NewFloat(NaN)"}) + } + return new(Float).SetFloat64(x) +} + +// Exponent and precision limits. +const ( + MaxExp = math.MaxInt32 // largest supported exponent + MinExp = math.MinInt32 // smallest supported exponent + MaxPrec = math.MaxUint32 // largest (theoretically) supported precision; likely memory-limited +) + +// Internal representation: The mantissa bits x.mant of a nonzero finite +// Float x are stored in a nat slice long enough to hold up to x.prec bits; +// the slice may (but doesn't have to) be shorter if the mantissa contains +// trailing 0 bits. x.mant is normalized if the msb of x.mant == 1 (i.e., +// the msb is shifted all the way "to the left"). Thus, if the mantissa has +// trailing 0 bits or x.prec is not a multiple of the Word size _W, +// x.mant[0] has trailing zero bits. The msb of the mantissa corresponds +// to the value 0.5; the exponent x.exp shifts the binary point as needed. +// +// A zero or non-finite Float x ignores x.mant and x.exp. +// +// x form neg mant exp +// ---------------------------------------------------------- +// ±0 zero sign - - +// 0 < |x| < +Inf finite sign mantissa exponent +// ±Inf inf sign - - + +// A form value describes the internal representation. +type form byte + +// The form value order is relevant - do not change! +const ( + zero form = iota + finite + inf +) + +// RoundingMode determines how a Float value is rounded to the +// desired precision. Rounding may change the Float value; the +// rounding error is described by the Float's Accuracy. +type RoundingMode byte + +// These constants define supported rounding modes. +const ( + ToNearestEven RoundingMode = iota // == IEEE 754-2008 roundTiesToEven + ToNearestAway // == IEEE 754-2008 roundTiesToAway + ToZero // == IEEE 754-2008 roundTowardZero + AwayFromZero // no IEEE 754-2008 equivalent + ToNegativeInf // == IEEE 754-2008 roundTowardNegative + ToPositiveInf // == IEEE 754-2008 roundTowardPositive +) + +//go:generate stringer -type=RoundingMode + +// Accuracy describes the rounding error produced by the most recent +// operation that generated a Float value, relative to the exact value. +type Accuracy int8 + +// Constants describing the Accuracy of a Float. +const ( + Below Accuracy = -1 + Exact Accuracy = 0 + Above Accuracy = +1 +) + +//go:generate stringer -type=Accuracy + +// SetPrec sets z's precision to prec and returns the (possibly) rounded +// value of z. Rounding occurs according to z's rounding mode if the mantissa +// cannot be represented in prec bits without loss of precision. +// SetPrec(0) maps all finite values to ±0; infinite values remain unchanged. +// If prec > MaxPrec, it is set to MaxPrec. +func (z *Float) SetPrec(prec uint) *Float { + z.acc = Exact // optimistically assume no rounding is needed + + // special case + if prec == 0 { + z.prec = 0 + if z.form == finite { + // truncate z to 0 + z.acc = makeAcc(z.neg) + z.form = zero + } + return z + } + + // general case + if prec > MaxPrec { + prec = MaxPrec + } + old := z.prec + z.prec = uint32(prec) + if z.prec < old { + z.round(0) + } + return z +} + +func makeAcc(above bool) Accuracy { + if above { + return Above + } + return Below +} + +// SetMode sets z's rounding mode to mode and returns an exact z. +// z remains unchanged otherwise. +// z.SetMode(z.Mode()) is a cheap way to set z's accuracy to Exact. +func (z *Float) SetMode(mode RoundingMode) *Float { + z.mode = mode + z.acc = Exact + return z +} + +// Prec returns the mantissa precision of x in bits. +// The result may be 0 for |x| == 0 and |x| == Inf. +func (x *Float) Prec() uint { + return uint(x.prec) +} + +// MinPrec returns the minimum precision required to represent x exactly +// (i.e., the smallest prec before x.SetPrec(prec) would start rounding x). +// The result is 0 for |x| == 0 and |x| == Inf. +func (x *Float) MinPrec() uint { + if x.form != finite { + return 0 + } + return uint(len(x.mant))*_W - x.mant.trailingZeroBits() +} + +// Mode returns the rounding mode of x. +func (x *Float) Mode() RoundingMode { + return x.mode +} + +// Acc returns the accuracy of x produced by the most recent +// operation, unless explicitly documented otherwise by that +// operation. +func (x *Float) Acc() Accuracy { + return x.acc +} + +// Sign returns: +// +// -1 if x < 0 +// 0 if x is ±0 +// +1 if x > 0 +// +func (x *Float) Sign() int { + if debugFloat { + x.validate() + } + if x.form == zero { + return 0 + } + if x.neg { + return -1 + } + return 1 +} + +// MantExp breaks x into its mantissa and exponent components +// and returns the exponent. If a non-nil mant argument is +// provided its value is set to the mantissa of x, with the +// same precision and rounding mode as x. The components +// satisfy x == mant × 2**exp, with 0.5 <= |mant| < 1.0. +// Calling MantExp with a nil argument is an efficient way to +// get the exponent of the receiver. +// +// Special cases are: +// +// ( ±0).MantExp(mant) = 0, with mant set to ±0 +// (±Inf).MantExp(mant) = 0, with mant set to ±Inf +// +// x and mant may be the same in which case x is set to its +// mantissa value. +func (x *Float) MantExp(mant *Float) (exp int) { + if debugFloat { + x.validate() + } + if x.form == finite { + exp = int(x.exp) + } + if mant != nil { + mant.Copy(x) + if mant.form == finite { + mant.exp = 0 + } + } + return +} + +func (z *Float) setExpAndRound(exp int64, sbit uint) { + if exp < MinExp { + // underflow + z.acc = makeAcc(z.neg) + z.form = zero + return + } + + if exp > MaxExp { + // overflow + z.acc = makeAcc(!z.neg) + z.form = inf + return + } + + z.form = finite + z.exp = int32(exp) + z.round(sbit) +} + +// SetMantExp sets z to mant × 2**exp and returns z. +// The result z has the same precision and rounding mode +// as mant. SetMantExp is an inverse of MantExp but does +// not require 0.5 <= |mant| < 1.0. Specifically, for a +// given x of type *Float, SetMantExp relates to MantExp +// as follows: +// +// mant := new(Float) +// new(Float).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0 +// +// Special cases are: +// +// z.SetMantExp( ±0, exp) = ±0 +// z.SetMantExp(±Inf, exp) = ±Inf +// +// z and mant may be the same in which case z's exponent +// is set to exp. +func (z *Float) SetMantExp(mant *Float, exp int) *Float { + if debugFloat { + z.validate() + mant.validate() + } + z.Copy(mant) + + if z.form == finite { + // 0 < |mant| < +Inf + z.setExpAndRound(int64(z.exp)+int64(exp), 0) + } + return z +} + +// Signbit reports whether x is negative or negative zero. +func (x *Float) Signbit() bool { + return x.neg +} + +// IsInf reports whether x is +Inf or -Inf. +func (x *Float) IsInf() bool { + return x.form == inf +} + +// IsInt reports whether x is an integer. +// ±Inf values are not integers. +func (x *Float) IsInt() bool { + if debugFloat { + x.validate() + } + // special cases + if x.form != finite { + return x.form == zero + } + // x.form == finite + if x.exp <= 0 { + return false + } + // x.exp > 0 + return x.prec <= uint32(x.exp) || x.MinPrec() <= uint(x.exp) // not enough bits for fractional mantissa +} + +// debugging support +func (x *Float) validate() { + if !debugFloat { + // avoid performance bugs + panic("validate called but debugFloat is not set") + } + if x.form != finite { + return + } + m := len(x.mant) + if m == 0 { + panic("nonzero finite number with empty mantissa") + } + const msb = 1 << (_W - 1) + if x.mant[m-1]&msb == 0 { + panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0))) + } + if x.prec == 0 { + panic("zero precision finite number") + } +} + +// round rounds z according to z.mode to z.prec bits and sets z.acc accordingly. +// sbit must be 0 or 1 and summarizes any "sticky bit" information one might +// have before calling round. z's mantissa must be normalized (with the msb set) +// or empty. +// +// CAUTION: The rounding modes ToNegativeInf, ToPositiveInf are affected by the +// sign of z. For correct rounding, the sign of z must be set correctly before +// calling round. +func (z *Float) round(sbit uint) { + if debugFloat { + z.validate() + } + + z.acc = Exact + if z.form != finite { + // ±0 or ±Inf => nothing left to do + return + } + // z.form == finite && len(z.mant) > 0 + // m > 0 implies z.prec > 0 (checked by validate) + + m := uint32(len(z.mant)) // present mantissa length in words + bits := m * _W // present mantissa bits; bits > 0 + if bits <= z.prec { + // mantissa fits => nothing to do + return + } + // bits > z.prec + + // Rounding is based on two bits: the rounding bit (rbit) and the + // sticky bit (sbit). The rbit is the bit immediately before the + // z.prec leading mantissa bits (the "0.5"). The sbit is set if any + // of the bits before the rbit are set (the "0.25", "0.125", etc.): + // + // rbit sbit => "fractional part" + // + // 0 0 == 0 + // 0 1 > 0 , < 0.5 + // 1 0 == 0.5 + // 1 1 > 0.5, < 1.0 + + // bits > z.prec: mantissa too large => round + r := uint(bits - z.prec - 1) // rounding bit position; r >= 0 + rbit := z.mant.bit(r) & 1 // rounding bit; be safe and ensure it's a single bit + // The sticky bit is only needed for rounding ToNearestEven + // or when the rounding bit is zero. Avoid computation otherwise. + if sbit == 0 && (rbit == 0 || z.mode == ToNearestEven) { + sbit = z.mant.sticky(r) + } + sbit &= 1 // be safe and ensure it's a single bit + + // cut off extra words + n := (z.prec + (_W - 1)) / _W // mantissa length in words for desired precision + if m > n { + copy(z.mant, z.mant[m-n:]) // move n last words to front + z.mant = z.mant[:n] + } + + // determine number of trailing zero bits (ntz) and compute lsb mask of mantissa's least-significant word + ntz := n*_W - z.prec // 0 <= ntz < _W + lsb := Word(1) << ntz + + // round if result is inexact + if rbit|sbit != 0 { + // Make rounding decision: The result mantissa is truncated ("rounded down") + // by default. Decide if we need to increment, or "round up", the (unsigned) + // mantissa. + inc := false + switch z.mode { + case ToNegativeInf: + inc = z.neg + case ToZero: + // nothing to do + case ToNearestEven: + inc = rbit != 0 && (sbit != 0 || z.mant[0]&lsb != 0) + case ToNearestAway: + inc = rbit != 0 + case AwayFromZero: + inc = true + case ToPositiveInf: + inc = !z.neg + default: + panic("unreachable") + } + + // A positive result (!z.neg) is Above the exact result if we increment, + // and it's Below if we truncate (Exact results require no rounding). + // For a negative result (z.neg) it is exactly the opposite. + z.acc = makeAcc(inc != z.neg) + + if inc { + // add 1 to mantissa + if addVW(z.mant, z.mant, lsb) != 0 { + // mantissa overflow => adjust exponent + if z.exp >= MaxExp { + // exponent overflow + z.form = inf + return + } + z.exp++ + // adjust mantissa: divide by 2 to compensate for exponent adjustment + shrVU(z.mant, z.mant, 1) + // set msb == carry == 1 from the mantissa overflow above + const msb = 1 << (_W - 1) + z.mant[n-1] |= msb + } + } + } + + // zero out trailing bits in least-significant word + z.mant[0] &^= lsb - 1 + + if debugFloat { + z.validate() + } +} + +func (z *Float) setBits64(neg bool, x uint64) *Float { + if z.prec == 0 { + z.prec = 64 + } + z.acc = Exact + z.neg = neg + if x == 0 { + z.form = zero + return z + } + // x != 0 + z.form = finite + s := bits.LeadingZeros64(x) + z.mant = z.mant.setUint64(x << uint(s)) + z.exp = int32(64 - s) // always fits + if z.prec < 64 { + z.round(0) + } + return z +} + +// SetUint64 sets z to the (possibly rounded) value of x and returns z. +// If z's precision is 0, it is changed to 64 (and rounding will have +// no effect). +func (z *Float) SetUint64(x uint64) *Float { + return z.setBits64(false, x) +} + +// SetInt64 sets z to the (possibly rounded) value of x and returns z. +// If z's precision is 0, it is changed to 64 (and rounding will have +// no effect). +func (z *Float) SetInt64(x int64) *Float { + u := x + if u < 0 { + u = -u + } + // We cannot simply call z.SetUint64(uint64(u)) and change + // the sign afterwards because the sign affects rounding. + return z.setBits64(x < 0, uint64(u)) +} + +// SetFloat64 sets z to the (possibly rounded) value of x and returns z. +// If z's precision is 0, it is changed to 53 (and rounding will have +// no effect). SetFloat64 panics with ErrNaN if x is a NaN. +func (z *Float) SetFloat64(x float64) *Float { + if z.prec == 0 { + z.prec = 53 + } + if math.IsNaN(x) { + panic(ErrNaN{"Float.SetFloat64(NaN)"}) + } + z.acc = Exact + z.neg = math.Signbit(x) // handle -0, -Inf correctly + if x == 0 { + z.form = zero + return z + } + if math.IsInf(x, 0) { + z.form = inf + return z + } + // normalized x != 0 + z.form = finite + fmant, exp := math.Frexp(x) // get normalized mantissa + z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11) + z.exp = int32(exp) // always fits + if z.prec < 53 { + z.round(0) + } + return z +} + +// fnorm normalizes mantissa m by shifting it to the left +// such that the msb of the most-significant word (msw) is 1. +// It returns the shift amount. It assumes that len(m) != 0. +func fnorm(m nat) int64 { + if debugFloat && (len(m) == 0 || m[len(m)-1] == 0) { + panic("msw of mantissa is 0") + } + s := nlz(m[len(m)-1]) + if s > 0 { + c := shlVU(m, m, s) + if debugFloat && c != 0 { + panic("nlz or shlVU incorrect") + } + } + return int64(s) +} + +// SetInt sets z to the (possibly rounded) value of x and returns z. +// If z's precision is 0, it is changed to the larger of x.BitLen() +// or 64 (and rounding will have no effect). +func (z *Float) SetInt(x *Int) *Float { + // TODO(gri) can be more efficient if z.prec > 0 + // but small compared to the size of x, or if there + // are many trailing 0's. + bits := uint32(x.BitLen()) + if z.prec == 0 { + z.prec = umax32(bits, 64) + } + z.acc = Exact + z.neg = x.neg + if len(x.abs) == 0 { + z.form = zero + return z + } + // x != 0 + z.mant = z.mant.set(x.abs) + fnorm(z.mant) + z.setExpAndRound(int64(bits), 0) + return z +} + +// SetRat sets z to the (possibly rounded) value of x and returns z. +// If z's precision is 0, it is changed to the largest of a.BitLen(), +// b.BitLen(), or 64; with x = a/b. +func (z *Float) SetRat(x *Rat) *Float { + if x.IsInt() { + return z.SetInt(x.Num()) + } + var a, b Float + a.SetInt(x.Num()) + b.SetInt(x.Denom()) + if z.prec == 0 { + z.prec = umax32(a.prec, b.prec) + } + return z.Quo(&a, &b) +} + +// SetInf sets z to the infinite Float -Inf if signbit is +// set, or +Inf if signbit is not set, and returns z. The +// precision of z is unchanged and the result is always +// Exact. +func (z *Float) SetInf(signbit bool) *Float { + z.acc = Exact + z.form = inf + z.neg = signbit + return z +} + +// Set sets z to the (possibly rounded) value of x and returns z. +// If z's precision is 0, it is changed to the precision of x +// before setting z (and rounding will have no effect). +// Rounding is performed according to z's precision and rounding +// mode; and z's accuracy reports the result error relative to the +// exact (not rounded) result. +func (z *Float) Set(x *Float) *Float { + if debugFloat { + x.validate() + } + z.acc = Exact + if z != x { + z.form = x.form + z.neg = x.neg + if x.form == finite { + z.exp = x.exp + z.mant = z.mant.set(x.mant) + } + if z.prec == 0 { + z.prec = x.prec + } else if z.prec < x.prec { + z.round(0) + } + } + return z +} + +// Copy sets z to x, with the same precision, rounding mode, and +// accuracy as x, and returns z. x is not changed even if z and +// x are the same. +func (z *Float) Copy(x *Float) *Float { + if debugFloat { + x.validate() + } + if z != x { + z.prec = x.prec + z.mode = x.mode + z.acc = x.acc + z.form = x.form + z.neg = x.neg + if z.form == finite { + z.mant = z.mant.set(x.mant) + z.exp = x.exp + } + } + return z +} + +// msb32 returns the 32 most significant bits of x. +func msb32(x nat) uint32 { + i := len(x) - 1 + if i < 0 { + return 0 + } + if debugFloat && x[i]&(1<<(_W-1)) == 0 { + panic("x not normalized") + } + switch _W { + case 32: + return uint32(x[i]) + case 64: + return uint32(x[i] >> 32) + } + panic("unreachable") +} + +// msb64 returns the 64 most significant bits of x. +func msb64(x nat) uint64 { + i := len(x) - 1 + if i < 0 { + return 0 + } + if debugFloat && x[i]&(1<<(_W-1)) == 0 { + panic("x not normalized") + } + switch _W { + case 32: + v := uint64(x[i]) << 32 + if i > 0 { + v |= uint64(x[i-1]) + } + return v + case 64: + return uint64(x[i]) + } + panic("unreachable") +} + +// Uint64 returns the unsigned integer resulting from truncating x +// towards zero. If 0 <= x <= math.MaxUint64, the result is Exact +// if x is an integer and Below otherwise. +// The result is (0, Above) for x < 0, and (math.MaxUint64, Below) +// for x > math.MaxUint64. +func (x *Float) Uint64() (uint64, Accuracy) { + if debugFloat { + x.validate() + } + + switch x.form { + case finite: + if x.neg { + return 0, Above + } + // 0 < x < +Inf + if x.exp <= 0 { + // 0 < x < 1 + return 0, Below + } + // 1 <= x < Inf + if x.exp <= 64 { + // u = trunc(x) fits into a uint64 + u := msb64(x.mant) >> (64 - uint32(x.exp)) + if x.MinPrec() <= 64 { + return u, Exact + } + return u, Below // x truncated + } + // x too large + return math.MaxUint64, Below + + case zero: + return 0, Exact + + case inf: + if x.neg { + return 0, Above + } + return math.MaxUint64, Below + } + + panic("unreachable") +} + +// Int64 returns the integer resulting from truncating x towards zero. +// If math.MinInt64 <= x <= math.MaxInt64, the result is Exact if x is +// an integer, and Above (x < 0) or Below (x > 0) otherwise. +// The result is (math.MinInt64, Above) for x < math.MinInt64, +// and (math.MaxInt64, Below) for x > math.MaxInt64. +func (x *Float) Int64() (int64, Accuracy) { + if debugFloat { + x.validate() + } + + switch x.form { + case finite: + // 0 < |x| < +Inf + acc := makeAcc(x.neg) + if x.exp <= 0 { + // 0 < |x| < 1 + return 0, acc + } + // x.exp > 0 + + // 1 <= |x| < +Inf + if x.exp <= 63 { + // i = trunc(x) fits into an int64 (excluding math.MinInt64) + i := int64(msb64(x.mant) >> (64 - uint32(x.exp))) + if x.neg { + i = -i + } + if x.MinPrec() <= uint(x.exp) { + return i, Exact + } + return i, acc // x truncated + } + if x.neg { + // check for special case x == math.MinInt64 (i.e., x == -(0.5 << 64)) + if x.exp == 64 && x.MinPrec() == 1 { + acc = Exact + } + return math.MinInt64, acc + } + // x too large + return math.MaxInt64, Below + + case zero: + return 0, Exact + + case inf: + if x.neg { + return math.MinInt64, Above + } + return math.MaxInt64, Below + } + + panic("unreachable") +} + +// Float32 returns the float32 value nearest to x. If x is too small to be +// represented by a float32 (|x| < math.SmallestNonzeroFloat32), the result +// is (0, Below) or (-0, Above), respectively, depending on the sign of x. +// If x is too large to be represented by a float32 (|x| > math.MaxFloat32), +// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x. +func (x *Float) Float32() (float32, Accuracy) { + if debugFloat { + x.validate() + } + + switch x.form { + case finite: + // 0 < |x| < +Inf + + const ( + fbits = 32 // float size + mbits = 23 // mantissa size (excluding implicit msb) + ebits = fbits - mbits - 1 // 8 exponent size + bias = 1<<(ebits-1) - 1 // 127 exponent bias + dmin = 1 - bias - mbits // -149 smallest unbiased exponent (denormal) + emin = 1 - bias // -126 smallest unbiased exponent (normal) + emax = bias // 127 largest unbiased exponent (normal) + ) + + // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float32 mantissa. + e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0 + + // Compute precision p for float32 mantissa. + // If the exponent is too small, we have a denormal number before + // rounding and fewer than p mantissa bits of precision available + // (the exponent remains fixed but the mantissa gets shifted right). + p := mbits + 1 // precision of normal float + if e < emin { + // recompute precision + p = mbits + 1 - emin + int(e) + // If p == 0, the mantissa of x is shifted so much to the right + // that its msb falls immediately to the right of the float32 + // mantissa space. In other words, if the smallest denormal is + // considered "1.0", for p == 0, the mantissa value m is >= 0.5. + // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal. + // If m == 0.5, it is rounded down to even, i.e., 0.0. + // If p < 0, the mantissa value m is <= "0.25" which is never rounded up. + if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ { + // underflow to ±0 + if x.neg { + var z float32 + return -z, Above + } + return 0.0, Below + } + // otherwise, round up + // We handle p == 0 explicitly because it's easy and because + // Float.round doesn't support rounding to 0 bits of precision. + if p == 0 { + if x.neg { + return -math.SmallestNonzeroFloat32, Below + } + return math.SmallestNonzeroFloat32, Above + } + } + // p > 0 + + // round + var r Float + r.prec = uint32(p) + r.Set(x) + e = r.exp - 1 + + // Rounding may have caused r to overflow to ±Inf + // (rounding never causes underflows to 0). + // If the exponent is too large, also overflow to ±Inf. + if r.form == inf || e > emax { + // overflow + if x.neg { + return float32(math.Inf(-1)), Below + } + return float32(math.Inf(+1)), Above + } + // e <= emax + + // Determine sign, biased exponent, and mantissa. + var sign, bexp, mant uint32 + if x.neg { + sign = 1 << (fbits - 1) + } + + // Rounding may have caused a denormal number to + // become normal. Check again. + if e < emin { + // denormal number: recompute precision + // Since rounding may have at best increased precision + // and we have eliminated p <= 0 early, we know p > 0. + // bexp == 0 for denormals + p = mbits + 1 - emin + int(e) + mant = msb32(r.mant) >> uint(fbits-p) + } else { + // normal number: emin <= e <= emax + bexp = uint32(e+bias) << mbits + mant = msb32(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit) + } + + return math.Float32frombits(sign | bexp | mant), r.acc + + case zero: + if x.neg { + var z float32 + return -z, Exact + } + return 0.0, Exact + + case inf: + if x.neg { + return float32(math.Inf(-1)), Exact + } + return float32(math.Inf(+1)), Exact + } + + panic("unreachable") +} + +// Float64 returns the float64 value nearest to x. If x is too small to be +// represented by a float64 (|x| < math.SmallestNonzeroFloat64), the result +// is (0, Below) or (-0, Above), respectively, depending on the sign of x. +// If x is too large to be represented by a float64 (|x| > math.MaxFloat64), +// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x. +func (x *Float) Float64() (float64, Accuracy) { + if debugFloat { + x.validate() + } + + switch x.form { + case finite: + // 0 < |x| < +Inf + + const ( + fbits = 64 // float size + mbits = 52 // mantissa size (excluding implicit msb) + ebits = fbits - mbits - 1 // 11 exponent size + bias = 1<<(ebits-1) - 1 // 1023 exponent bias + dmin = 1 - bias - mbits // -1074 smallest unbiased exponent (denormal) + emin = 1 - bias // -1022 smallest unbiased exponent (normal) + emax = bias // 1023 largest unbiased exponent (normal) + ) + + // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float64 mantissa. + e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0 + + // Compute precision p for float64 mantissa. + // If the exponent is too small, we have a denormal number before + // rounding and fewer than p mantissa bits of precision available + // (the exponent remains fixed but the mantissa gets shifted right). + p := mbits + 1 // precision of normal float + if e < emin { + // recompute precision + p = mbits + 1 - emin + int(e) + // If p == 0, the mantissa of x is shifted so much to the right + // that its msb falls immediately to the right of the float64 + // mantissa space. In other words, if the smallest denormal is + // considered "1.0", for p == 0, the mantissa value m is >= 0.5. + // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal. + // If m == 0.5, it is rounded down to even, i.e., 0.0. + // If p < 0, the mantissa value m is <= "0.25" which is never rounded up. + if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ { + // underflow to ±0 + if x.neg { + var z float64 + return -z, Above + } + return 0.0, Below + } + // otherwise, round up + // We handle p == 0 explicitly because it's easy and because + // Float.round doesn't support rounding to 0 bits of precision. + if p == 0 { + if x.neg { + return -math.SmallestNonzeroFloat64, Below + } + return math.SmallestNonzeroFloat64, Above + } + } + // p > 0 + + // round + var r Float + r.prec = uint32(p) + r.Set(x) + e = r.exp - 1 + + // Rounding may have caused r to overflow to ±Inf + // (rounding never causes underflows to 0). + // If the exponent is too large, also overflow to ±Inf. + if r.form == inf || e > emax { + // overflow + if x.neg { + return math.Inf(-1), Below + } + return math.Inf(+1), Above + } + // e <= emax + + // Determine sign, biased exponent, and mantissa. + var sign, bexp, mant uint64 + if x.neg { + sign = 1 << (fbits - 1) + } + + // Rounding may have caused a denormal number to + // become normal. Check again. + if e < emin { + // denormal number: recompute precision + // Since rounding may have at best increased precision + // and we have eliminated p <= 0 early, we know p > 0. + // bexp == 0 for denormals + p = mbits + 1 - emin + int(e) + mant = msb64(r.mant) >> uint(fbits-p) + } else { + // normal number: emin <= e <= emax + bexp = uint64(e+bias) << mbits + mant = msb64(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit) + } + + return math.Float64frombits(sign | bexp | mant), r.acc + + case zero: + if x.neg { + var z float64 + return -z, Exact + } + return 0.0, Exact + + case inf: + if x.neg { + return math.Inf(-1), Exact + } + return math.Inf(+1), Exact + } + + panic("unreachable") +} + +// Int returns the result of truncating x towards zero; +// or nil if x is an infinity. +// The result is Exact if x.IsInt(); otherwise it is Below +// for x > 0, and Above for x < 0. +// If a non-nil *Int argument z is provided, Int stores +// the result in z instead of allocating a new Int. +func (x *Float) Int(z *Int) (*Int, Accuracy) { + if debugFloat { + x.validate() + } + + if z == nil && x.form <= finite { + z = new(Int) + } + + switch x.form { + case finite: + // 0 < |x| < +Inf + acc := makeAcc(x.neg) + if x.exp <= 0 { + // 0 < |x| < 1 + return z.SetInt64(0), acc + } + // x.exp > 0 + + // 1 <= |x| < +Inf + // determine minimum required precision for x + allBits := uint(len(x.mant)) * _W + exp := uint(x.exp) + if x.MinPrec() <= exp { + acc = Exact + } + // shift mantissa as needed + if z == nil { + z = new(Int) + } + z.neg = x.neg + switch { + case exp > allBits: + z.abs = z.abs.shl(x.mant, exp-allBits) + default: + z.abs = z.abs.set(x.mant) + case exp < allBits: + z.abs = z.abs.shr(x.mant, allBits-exp) + } + return z, acc + + case zero: + return z.SetInt64(0), Exact + + case inf: + return nil, makeAcc(x.neg) + } + + panic("unreachable") +} + +// Rat returns the rational number corresponding to x; +// or nil if x is an infinity. +// The result is Exact if x is not an Inf. +// If a non-nil *Rat argument z is provided, Rat stores +// the result in z instead of allocating a new Rat. +func (x *Float) Rat(z *Rat) (*Rat, Accuracy) { + if debugFloat { + x.validate() + } + + if z == nil && x.form <= finite { + z = new(Rat) + } + + switch x.form { + case finite: + // 0 < |x| < +Inf + allBits := int32(len(x.mant)) * _W + // build up numerator and denominator + z.a.neg = x.neg + switch { + case x.exp > allBits: + z.a.abs = z.a.abs.shl(x.mant, uint(x.exp-allBits)) + z.b.abs = z.b.abs[:0] // == 1 (see Rat) + // z already in normal form + default: + z.a.abs = z.a.abs.set(x.mant) + z.b.abs = z.b.abs[:0] // == 1 (see Rat) + // z already in normal form + case x.exp < allBits: + z.a.abs = z.a.abs.set(x.mant) + t := z.b.abs.setUint64(1) + z.b.abs = t.shl(t, uint(allBits-x.exp)) + z.norm() + } + return z, Exact + + case zero: + return z.SetInt64(0), Exact + + case inf: + return nil, makeAcc(x.neg) + } + + panic("unreachable") +} + +// Abs sets z to the (possibly rounded) value |x| (the absolute value of x) +// and returns z. +func (z *Float) Abs(x *Float) *Float { + z.Set(x) + z.neg = false + return z +} + +// Neg sets z to the (possibly rounded) value of x with its sign negated, +// and returns z. +func (z *Float) Neg(x *Float) *Float { + z.Set(x) + z.neg = !z.neg + return z +} + +func validateBinaryOperands(x, y *Float) { + if !debugFloat { + // avoid performance bugs + panic("validateBinaryOperands called but debugFloat is not set") + } + if len(x.mant) == 0 { + panic("empty mantissa for x") + } + if len(y.mant) == 0 { + panic("empty mantissa for y") + } +} + +// z = x + y, ignoring signs of x and y for the addition +// but using the sign of z for rounding the result. +// x and y must have a non-empty mantissa and valid exponent. +func (z *Float) uadd(x, y *Float) { + // Note: This implementation requires 2 shifts most of the + // time. It is also inefficient if exponents or precisions + // differ by wide margins. The following article describes + // an efficient (but much more complicated) implementation + // compatible with the internal representation used here: + // + // Vincent Lefèvre: "The Generic Multiple-Precision Floating- + // Point Addition With Exact Rounding (as in the MPFR Library)" + // http://www.vinc17.net/research/papers/rnc6.pdf + + if debugFloat { + validateBinaryOperands(x, y) + } + + // compute exponents ex, ey for mantissa with "binary point" + // on the right (mantissa.0) - use int64 to avoid overflow + ex := int64(x.exp) - int64(len(x.mant))*_W + ey := int64(y.exp) - int64(len(y.mant))*_W + + al := alias(z.mant, x.mant) || alias(z.mant, y.mant) + + // TODO(gri) having a combined add-and-shift primitive + // could make this code significantly faster + switch { + case ex < ey: + if al { + t := nat(nil).shl(y.mant, uint(ey-ex)) + z.mant = z.mant.add(x.mant, t) + } else { + z.mant = z.mant.shl(y.mant, uint(ey-ex)) + z.mant = z.mant.add(x.mant, z.mant) + } + default: + // ex == ey, no shift needed + z.mant = z.mant.add(x.mant, y.mant) + case ex > ey: + if al { + t := nat(nil).shl(x.mant, uint(ex-ey)) + z.mant = z.mant.add(t, y.mant) + } else { + z.mant = z.mant.shl(x.mant, uint(ex-ey)) + z.mant = z.mant.add(z.mant, y.mant) + } + ex = ey + } + // len(z.mant) > 0 + + z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0) +} + +// z = x - y for |x| > |y|, ignoring signs of x and y for the subtraction +// but using the sign of z for rounding the result. +// x and y must have a non-empty mantissa and valid exponent. +func (z *Float) usub(x, y *Float) { + // This code is symmetric to uadd. + // We have not factored the common code out because + // eventually uadd (and usub) should be optimized + // by special-casing, and the code will diverge. + + if debugFloat { + validateBinaryOperands(x, y) + } + + ex := int64(x.exp) - int64(len(x.mant))*_W + ey := int64(y.exp) - int64(len(y.mant))*_W + + al := alias(z.mant, x.mant) || alias(z.mant, y.mant) + + switch { + case ex < ey: + if al { + t := nat(nil).shl(y.mant, uint(ey-ex)) + z.mant = t.sub(x.mant, t) + } else { + z.mant = z.mant.shl(y.mant, uint(ey-ex)) + z.mant = z.mant.sub(x.mant, z.mant) + } + default: + // ex == ey, no shift needed + z.mant = z.mant.sub(x.mant, y.mant) + case ex > ey: + if al { + t := nat(nil).shl(x.mant, uint(ex-ey)) + z.mant = t.sub(t, y.mant) + } else { + z.mant = z.mant.shl(x.mant, uint(ex-ey)) + z.mant = z.mant.sub(z.mant, y.mant) + } + ex = ey + } + + // operands may have canceled each other out + if len(z.mant) == 0 { + z.acc = Exact + z.form = zero + z.neg = false + return + } + // len(z.mant) > 0 + + z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0) +} + +// z = x * y, ignoring signs of x and y for the multiplication +// but using the sign of z for rounding the result. +// x and y must have a non-empty mantissa and valid exponent. +func (z *Float) umul(x, y *Float) { + if debugFloat { + validateBinaryOperands(x, y) + } + + // Note: This is doing too much work if the precision + // of z is less than the sum of the precisions of x + // and y which is often the case (e.g., if all floats + // have the same precision). + // TODO(gri) Optimize this for the common case. + + e := int64(x.exp) + int64(y.exp) + if x == y { + z.mant = z.mant.sqr(x.mant) + } else { + z.mant = z.mant.mul(x.mant, y.mant) + } + z.setExpAndRound(e-fnorm(z.mant), 0) +} + +// z = x / y, ignoring signs of x and y for the division +// but using the sign of z for rounding the result. +// x and y must have a non-empty mantissa and valid exponent. +func (z *Float) uquo(x, y *Float) { + if debugFloat { + validateBinaryOperands(x, y) + } + + // mantissa length in words for desired result precision + 1 + // (at least one extra bit so we get the rounding bit after + // the division) + n := int(z.prec/_W) + 1 + + // compute adjusted x.mant such that we get enough result precision + xadj := x.mant + if d := n - len(x.mant) + len(y.mant); d > 0 { + // d extra words needed => add d "0 digits" to x + xadj = make(nat, len(x.mant)+d) + copy(xadj[d:], x.mant) + } + // TODO(gri): If we have too many digits (d < 0), we should be able + // to shorten x for faster division. But we must be extra careful + // with rounding in that case. + + // Compute d before division since there may be aliasing of x.mant + // (via xadj) or y.mant with z.mant. + d := len(xadj) - len(y.mant) + + // divide + var r nat + z.mant, r = z.mant.div(nil, xadj, y.mant) + e := int64(x.exp) - int64(y.exp) - int64(d-len(z.mant))*_W + + // The result is long enough to include (at least) the rounding bit. + // If there's a non-zero remainder, the corresponding fractional part + // (if it were computed), would have a non-zero sticky bit (if it were + // zero, it couldn't have a non-zero remainder). + var sbit uint + if len(r) > 0 { + sbit = 1 + } + + z.setExpAndRound(e-fnorm(z.mant), sbit) +} + +// ucmp returns -1, 0, or +1, depending on whether +// |x| < |y|, |x| == |y|, or |x| > |y|. +// x and y must have a non-empty mantissa and valid exponent. +func (x *Float) ucmp(y *Float) int { + if debugFloat { + validateBinaryOperands(x, y) + } + + switch { + case x.exp < y.exp: + return -1 + case x.exp > y.exp: + return +1 + } + // x.exp == y.exp + + // compare mantissas + i := len(x.mant) + j := len(y.mant) + for i > 0 || j > 0 { + var xm, ym Word + if i > 0 { + i-- + xm = x.mant[i] + } + if j > 0 { + j-- + ym = y.mant[j] + } + switch { + case xm < ym: + return -1 + case xm > ym: + return +1 + } + } + + return 0 +} + +// Handling of sign bit as defined by IEEE 754-2008, section 6.3: +// +// When neither the inputs nor result are NaN, the sign of a product or +// quotient is the exclusive OR of the operands’ signs; the sign of a sum, +// or of a difference x−y regarded as a sum x+(−y), differs from at most +// one of the addends’ signs; and the sign of the result of conversions, +// the quantize operation, the roundToIntegral operations, and the +// roundToIntegralExact (see 5.3.1) is the sign of the first or only operand. +// These rules shall apply even when operands or results are zero or infinite. +// +// When the sum of two operands with opposite signs (or the difference of +// two operands with like signs) is exactly zero, the sign of that sum (or +// difference) shall be +0 in all rounding-direction attributes except +// roundTowardNegative; under that attribute, the sign of an exact zero +// sum (or difference) shall be −0. However, x+x = x−(−x) retains the same +// sign as x even when x is zero. +// +// See also: https://play.golang.org/p/RtH3UCt5IH + +// Add sets z to the rounded sum x+y and returns z. If z's precision is 0, +// it is changed to the larger of x's or y's precision before the operation. +// Rounding is performed according to z's precision and rounding mode; and +// z's accuracy reports the result error relative to the exact (not rounded) +// result. Add panics with ErrNaN if x and y are infinities with opposite +// signs. The value of z is undefined in that case. +func (z *Float) Add(x, y *Float) *Float { + if debugFloat { + x.validate() + y.validate() + } + + if z.prec == 0 { + z.prec = umax32(x.prec, y.prec) + } + + if x.form == finite && y.form == finite { + // x + y (common case) + + // Below we set z.neg = x.neg, and when z aliases y this will + // change the y operand's sign. This is fine, because if an + // operand aliases the receiver it'll be overwritten, but we still + // want the original x.neg and y.neg values when we evaluate + // x.neg != y.neg, so we need to save y.neg before setting z.neg. + yneg := y.neg + + z.neg = x.neg + if x.neg == yneg { + // x + y == x + y + // (-x) + (-y) == -(x + y) + z.uadd(x, y) + } else { + // x + (-y) == x - y == -(y - x) + // (-x) + y == y - x == -(x - y) + if x.ucmp(y) > 0 { + z.usub(x, y) + } else { + z.neg = !z.neg + z.usub(y, x) + } + } + if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact { + z.neg = true + } + return z + } + + if x.form == inf && y.form == inf && x.neg != y.neg { + // +Inf + -Inf + // -Inf + +Inf + // value of z is undefined but make sure it's valid + z.acc = Exact + z.form = zero + z.neg = false + panic(ErrNaN{"addition of infinities with opposite signs"}) + } + + if x.form == zero && y.form == zero { + // ±0 + ±0 + z.acc = Exact + z.form = zero + z.neg = x.neg && y.neg // -0 + -0 == -0 + return z + } + + if x.form == inf || y.form == zero { + // ±Inf + y + // x + ±0 + return z.Set(x) + } + + // ±0 + y + // x + ±Inf + return z.Set(y) +} + +// Sub sets z to the rounded difference x-y and returns z. +// Precision, rounding, and accuracy reporting are as for Add. +// Sub panics with ErrNaN if x and y are infinities with equal +// signs. The value of z is undefined in that case. +func (z *Float) Sub(x, y *Float) *Float { + if debugFloat { + x.validate() + y.validate() + } + + if z.prec == 0 { + z.prec = umax32(x.prec, y.prec) + } + + if x.form == finite && y.form == finite { + // x - y (common case) + yneg := y.neg + z.neg = x.neg + if x.neg != yneg { + // x - (-y) == x + y + // (-x) - y == -(x + y) + z.uadd(x, y) + } else { + // x - y == x - y == -(y - x) + // (-x) - (-y) == y - x == -(x - y) + if x.ucmp(y) > 0 { + z.usub(x, y) + } else { + z.neg = !z.neg + z.usub(y, x) + } + } + if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact { + z.neg = true + } + return z + } + + if x.form == inf && y.form == inf && x.neg == y.neg { + // +Inf - +Inf + // -Inf - -Inf + // value of z is undefined but make sure it's valid + z.acc = Exact + z.form = zero + z.neg = false + panic(ErrNaN{"subtraction of infinities with equal signs"}) + } + + if x.form == zero && y.form == zero { + // ±0 - ±0 + z.acc = Exact + z.form = zero + z.neg = x.neg && !y.neg // -0 - +0 == -0 + return z + } + + if x.form == inf || y.form == zero { + // ±Inf - y + // x - ±0 + return z.Set(x) + } + + // ±0 - y + // x - ±Inf + return z.Neg(y) +} + +// Mul sets z to the rounded product x*y and returns z. +// Precision, rounding, and accuracy reporting are as for Add. +// Mul panics with ErrNaN if one operand is zero and the other +// operand an infinity. The value of z is undefined in that case. +func (z *Float) Mul(x, y *Float) *Float { + if debugFloat { + x.validate() + y.validate() + } + + if z.prec == 0 { + z.prec = umax32(x.prec, y.prec) + } + + z.neg = x.neg != y.neg + + if x.form == finite && y.form == finite { + // x * y (common case) + z.umul(x, y) + return z + } + + z.acc = Exact + if x.form == zero && y.form == inf || x.form == inf && y.form == zero { + // ±0 * ±Inf + // ±Inf * ±0 + // value of z is undefined but make sure it's valid + z.form = zero + z.neg = false + panic(ErrNaN{"multiplication of zero with infinity"}) + } + + if x.form == inf || y.form == inf { + // ±Inf * y + // x * ±Inf + z.form = inf + return z + } + + // ±0 * y + // x * ±0 + z.form = zero + return z +} + +// Quo sets z to the rounded quotient x/y and returns z. +// Precision, rounding, and accuracy reporting are as for Add. +// Quo panics with ErrNaN if both operands are zero or infinities. +// The value of z is undefined in that case. +func (z *Float) Quo(x, y *Float) *Float { + if debugFloat { + x.validate() + y.validate() + } + + if z.prec == 0 { + z.prec = umax32(x.prec, y.prec) + } + + z.neg = x.neg != y.neg + + if x.form == finite && y.form == finite { + // x / y (common case) + z.uquo(x, y) + return z + } + + z.acc = Exact + if x.form == zero && y.form == zero || x.form == inf && y.form == inf { + // ±0 / ±0 + // ±Inf / ±Inf + // value of z is undefined but make sure it's valid + z.form = zero + z.neg = false + panic(ErrNaN{"division of zero by zero or infinity by infinity"}) + } + + if x.form == zero || y.form == inf { + // ±0 / y + // x / ±Inf + z.form = zero + return z + } + + // x / ±0 + // ±Inf / y + z.form = inf + return z +} + +// Cmp compares x and y and returns: +// +// -1 if x < y +// 0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf) +// +1 if x > y +// +func (x *Float) Cmp(y *Float) int { + if debugFloat { + x.validate() + y.validate() + } + + mx := x.ord() + my := y.ord() + switch { + case mx < my: + return -1 + case mx > my: + return +1 + } + // mx == my + + // only if |mx| == 1 we have to compare the mantissae + switch mx { + case -1: + return y.ucmp(x) + case +1: + return x.ucmp(y) + } + + return 0 +} + +// ord classifies x and returns: +// +// -2 if -Inf == x +// -1 if -Inf < x < 0 +// 0 if x == 0 (signed or unsigned) +// +1 if 0 < x < +Inf +// +2 if x == +Inf +// +func (x *Float) ord() int { + var m int + switch x.form { + case finite: + m = 1 + case zero: + return 0 + case inf: + m = 2 + } + if x.neg { + m = -m + } + return m +} + +func umax32(x, y uint32) uint32 { + if x > y { + return x + } + return y +} diff --git a/contrib/go/_std_1.18/src/math/big/floatconv.go b/contrib/go/_std_1.18/src/math/big/floatconv.go new file mode 100644 index 0000000000..57b7df3936 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/floatconv.go @@ -0,0 +1,304 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements string-to-Float conversion functions. + +package big + +import ( + "fmt" + "io" + "strings" +) + +var floatZero Float + +// SetString sets z to the value of s and returns z and a boolean indicating +// success. s must be a floating-point number of the same format as accepted +// by Parse, with base argument 0. The entire string (not just a prefix) must +// be valid for success. If the operation failed, the value of z is undefined +// but the returned value is nil. +func (z *Float) SetString(s string) (*Float, bool) { + if f, _, err := z.Parse(s, 0); err == nil { + return f, true + } + return nil, false +} + +// scan is like Parse but reads the longest possible prefix representing a valid +// floating point number from an io.ByteScanner rather than a string. It serves +// as the implementation of Parse. It does not recognize ±Inf and does not expect +// EOF at the end. +func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) { + prec := z.prec + if prec == 0 { + prec = 64 + } + + // A reasonable value in case of an error. + z.form = zero + + // sign + z.neg, err = scanSign(r) + if err != nil { + return + } + + // mantissa + var fcount int // fractional digit count; valid if <= 0 + z.mant, b, fcount, err = z.mant.scan(r, base, true) + if err != nil { + return + } + + // exponent + var exp int64 + var ebase int + exp, ebase, err = scanExponent(r, true, base == 0) + if err != nil { + return + } + + // special-case 0 + if len(z.mant) == 0 { + z.prec = prec + z.acc = Exact + z.form = zero + f = z + return + } + // len(z.mant) > 0 + + // The mantissa may have a radix point (fcount <= 0) and there + // may be a nonzero exponent exp. The radix point amounts to a + // division by b**(-fcount). An exponent means multiplication by + // ebase**exp. Finally, mantissa normalization (shift left) requires + // a correcting multiplication by 2**(-shiftcount). Multiplications + // are commutative, so we can apply them in any order as long as there + // is no loss of precision. We only have powers of 2 and 10, and + // we split powers of 10 into the product of the same powers of + // 2 and 5. This reduces the size of the multiplication factor + // needed for base-10 exponents. + + // normalize mantissa and determine initial exponent contributions + exp2 := int64(len(z.mant))*_W - fnorm(z.mant) + exp5 := int64(0) + + // determine binary or decimal exponent contribution of radix point + if fcount < 0 { + // The mantissa has a radix point ddd.dddd; and + // -fcount is the number of digits to the right + // of '.'. Adjust relevant exponent accordingly. + d := int64(fcount) + switch b { + case 10: + exp5 = d + fallthrough // 10**e == 5**e * 2**e + case 2: + exp2 += d + case 8: + exp2 += d * 3 // octal digits are 3 bits each + case 16: + exp2 += d * 4 // hexadecimal digits are 4 bits each + default: + panic("unexpected mantissa base") + } + // fcount consumed - not needed anymore + } + + // take actual exponent into account + switch ebase { + case 10: + exp5 += exp + fallthrough // see fallthrough above + case 2: + exp2 += exp + default: + panic("unexpected exponent base") + } + // exp consumed - not needed anymore + + // apply 2**exp2 + if MinExp <= exp2 && exp2 <= MaxExp { + z.prec = prec + z.form = finite + z.exp = int32(exp2) + f = z + } else { + err = fmt.Errorf("exponent overflow") + return + } + + if exp5 == 0 { + // no decimal exponent contribution + z.round(0) + return + } + // exp5 != 0 + + // apply 5**exp5 + p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number? + if exp5 < 0 { + z.Quo(z, p.pow5(uint64(-exp5))) + } else { + z.Mul(z, p.pow5(uint64(exp5))) + } + + return +} + +// These powers of 5 fit into a uint64. +// +// for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 { +// fmt.Println(q) +// } +// +var pow5tab = [...]uint64{ + 1, + 5, + 25, + 125, + 625, + 3125, + 15625, + 78125, + 390625, + 1953125, + 9765625, + 48828125, + 244140625, + 1220703125, + 6103515625, + 30517578125, + 152587890625, + 762939453125, + 3814697265625, + 19073486328125, + 95367431640625, + 476837158203125, + 2384185791015625, + 11920928955078125, + 59604644775390625, + 298023223876953125, + 1490116119384765625, + 7450580596923828125, +} + +// pow5 sets z to 5**n and returns z. +// n must not be negative. +func (z *Float) pow5(n uint64) *Float { + const m = uint64(len(pow5tab) - 1) + if n <= m { + return z.SetUint64(pow5tab[n]) + } + // n > m + + z.SetUint64(pow5tab[m]) + n -= m + + // use more bits for f than for z + // TODO(gri) what is the right number? + f := new(Float).SetPrec(z.Prec() + 64).SetUint64(5) + + for n > 0 { + if n&1 != 0 { + z.Mul(z, f) + } + f.Mul(f, f) + n >>= 1 + } + + return z +} + +// Parse parses s which must contain a text representation of a floating- +// point number with a mantissa in the given conversion base (the exponent +// is always a decimal number), or a string representing an infinite value. +// +// For base 0, an underscore character ``_'' may appear between a base +// prefix and an adjacent digit, and between successive digits; such +// underscores do not change the value of the number, or the returned +// digit count. Incorrect placement of underscores is reported as an +// error if there are no other errors. If base != 0, underscores are +// not recognized and thus terminate scanning like any other character +// that is not a valid radix point or digit. +// +// It sets z to the (possibly rounded) value of the corresponding floating- +// point value, and returns z, the actual base b, and an error err, if any. +// The entire string (not just a prefix) must be consumed for success. +// If z's precision is 0, it is changed to 64 before rounding takes effect. +// The number must be of the form: +// +// number = [ sign ] ( float | "inf" | "Inf" ) . +// sign = "+" | "-" . +// float = ( mantissa | prefix pmantissa ) [ exponent ] . +// prefix = "0" [ "b" | "B" | "o" | "O" | "x" | "X" ] . +// mantissa = digits "." [ digits ] | digits | "." digits . +// pmantissa = [ "_" ] digits "." [ digits ] | [ "_" ] digits | "." digits . +// exponent = ( "e" | "E" | "p" | "P" ) [ sign ] digits . +// digits = digit { [ "_" ] digit } . +// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" . +// +// The base argument must be 0, 2, 8, 10, or 16. Providing an invalid base +// argument will lead to a run-time panic. +// +// For base 0, the number prefix determines the actual base: A prefix of +// ``0b'' or ``0B'' selects base 2, ``0o'' or ``0O'' selects base 8, and +// ``0x'' or ``0X'' selects base 16. Otherwise, the actual base is 10 and +// no prefix is accepted. The octal prefix "0" is not supported (a leading +// "0" is simply considered a "0"). +// +// A "p" or "P" exponent indicates a base 2 (rather then base 10) exponent; +// for instance, "0x1.fffffffffffffp1023" (using base 0) represents the +// maximum float64 value. For hexadecimal mantissae, the exponent character +// must be one of 'p' or 'P', if present (an "e" or "E" exponent indicator +// cannot be distinguished from a mantissa digit). +// +// The returned *Float f is nil and the value of z is valid but not +// defined if an error is reported. +// +func (z *Float) Parse(s string, base int) (f *Float, b int, err error) { + // scan doesn't handle ±Inf + if len(s) == 3 && (s == "Inf" || s == "inf") { + f = z.SetInf(false) + return + } + if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") { + f = z.SetInf(s[0] == '-') + return + } + + r := strings.NewReader(s) + if f, b, err = z.scan(r, base); err != nil { + return + } + + // entire string must have been consumed + if ch, err2 := r.ReadByte(); err2 == nil { + err = fmt.Errorf("expected end of string, found %q", ch) + } else if err2 != io.EOF { + err = err2 + } + + return +} + +// ParseFloat is like f.Parse(s, base) with f set to the given precision +// and rounding mode. +func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) { + return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base) +} + +var _ fmt.Scanner = (*Float)(nil) // *Float must implement fmt.Scanner + +// Scan is a support routine for fmt.Scanner; it sets z to the value of +// the scanned number. It accepts formats whose verbs are supported by +// fmt.Scan for floating point values, which are: +// 'b' (binary), 'e', 'E', 'f', 'F', 'g' and 'G'. +// Scan doesn't handle ±Inf. +func (z *Float) Scan(s fmt.ScanState, ch rune) error { + s.SkipSpace() + _, _, err := z.scan(byteReader{s}, 0) + return err +} diff --git a/contrib/go/_std_1.18/src/math/big/floatmarsh.go b/contrib/go/_std_1.18/src/math/big/floatmarsh.go new file mode 100644 index 0000000000..d1c1dab069 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/floatmarsh.go @@ -0,0 +1,120 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements encoding/decoding of Floats. + +package big + +import ( + "encoding/binary" + "fmt" +) + +// Gob codec version. Permits backward-compatible changes to the encoding. +const floatGobVersion byte = 1 + +// GobEncode implements the gob.GobEncoder interface. +// The Float value and all its attributes (precision, +// rounding mode, accuracy) are marshaled. +func (x *Float) GobEncode() ([]byte, error) { + if x == nil { + return nil, nil + } + + // determine max. space (bytes) required for encoding + sz := 1 + 1 + 4 // version + mode|acc|form|neg (3+2+2+1bit) + prec + n := 0 // number of mantissa words + if x.form == finite { + // add space for mantissa and exponent + n = int((x.prec + (_W - 1)) / _W) // required mantissa length in words for given precision + // actual mantissa slice could be shorter (trailing 0's) or longer (unused bits): + // - if shorter, only encode the words present + // - if longer, cut off unused words when encoding in bytes + // (in practice, this should never happen since rounding + // takes care of it, but be safe and do it always) + if len(x.mant) < n { + n = len(x.mant) + } + // len(x.mant) >= n + sz += 4 + n*_S // exp + mant + } + buf := make([]byte, sz) + + buf[0] = floatGobVersion + b := byte(x.mode&7)<<5 | byte((x.acc+1)&3)<<3 | byte(x.form&3)<<1 + if x.neg { + b |= 1 + } + buf[1] = b + binary.BigEndian.PutUint32(buf[2:], x.prec) + + if x.form == finite { + binary.BigEndian.PutUint32(buf[6:], uint32(x.exp)) + x.mant[len(x.mant)-n:].bytes(buf[10:]) // cut off unused trailing words + } + + return buf, nil +} + +// GobDecode implements the gob.GobDecoder interface. +// The result is rounded per the precision and rounding mode of +// z unless z's precision is 0, in which case z is set exactly +// to the decoded value. +func (z *Float) GobDecode(buf []byte) error { + if len(buf) == 0 { + // Other side sent a nil or default value. + *z = Float{} + return nil + } + + if buf[0] != floatGobVersion { + return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0]) + } + + oldPrec := z.prec + oldMode := z.mode + + b := buf[1] + z.mode = RoundingMode((b >> 5) & 7) + z.acc = Accuracy((b>>3)&3) - 1 + z.form = form((b >> 1) & 3) + z.neg = b&1 != 0 + z.prec = binary.BigEndian.Uint32(buf[2:]) + + if z.form == finite { + z.exp = int32(binary.BigEndian.Uint32(buf[6:])) + z.mant = z.mant.setBytes(buf[10:]) + } + + if oldPrec != 0 { + z.mode = oldMode + z.SetPrec(uint(oldPrec)) + } + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +// Only the Float value is marshaled (in full precision), other +// attributes such as precision or accuracy are ignored. +func (x *Float) MarshalText() (text []byte, err error) { + if x == nil { + return []byte("<nil>"), nil + } + var buf []byte + return x.Append(buf, 'g', -1), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// The result is rounded per the precision and rounding mode of z. +// If z's precision is 0, it is changed to 64 before rounding takes +// effect. +func (z *Float) UnmarshalText(text []byte) error { + // TODO(gri): get rid of the []byte/string conversion + _, _, err := z.Parse(string(text), 0) + if err != nil { + err = fmt.Errorf("math/big: cannot unmarshal %q into a *big.Float (%v)", text, err) + } + return err +} diff --git a/contrib/go/_std_1.18/src/math/big/ftoa.go b/contrib/go/_std_1.18/src/math/big/ftoa.go new file mode 100644 index 0000000000..5506e6e425 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/ftoa.go @@ -0,0 +1,536 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements Float-to-string conversion functions. +// It is closely following the corresponding implementation +// in strconv/ftoa.go, but modified and simplified for Float. + +package big + +import ( + "bytes" + "fmt" + "strconv" +) + +// Text converts the floating-point number x to a string according +// to the given format and precision prec. The format is one of: +// +// 'e' -d.dddde±dd, decimal exponent, at least two (possibly 0) exponent digits +// 'E' -d.ddddE±dd, decimal exponent, at least two (possibly 0) exponent digits +// 'f' -ddddd.dddd, no exponent +// 'g' like 'e' for large exponents, like 'f' otherwise +// 'G' like 'E' for large exponents, like 'f' otherwise +// 'x' -0xd.dddddp±dd, hexadecimal mantissa, decimal power of two exponent +// 'p' -0x.dddp±dd, hexadecimal mantissa, decimal power of two exponent (non-standard) +// 'b' -ddddddp±dd, decimal mantissa, decimal power of two exponent (non-standard) +// +// For the power-of-two exponent formats, the mantissa is printed in normalized form: +// +// 'x' hexadecimal mantissa in [1, 2), or 0 +// 'p' hexadecimal mantissa in [½, 1), or 0 +// 'b' decimal integer mantissa using x.Prec() bits, or 0 +// +// Note that the 'x' form is the one used by most other languages and libraries. +// +// If format is a different character, Text returns a "%" followed by the +// unrecognized format character. +// +// The precision prec controls the number of digits (excluding the exponent) +// printed by the 'e', 'E', 'f', 'g', 'G', and 'x' formats. +// For 'e', 'E', 'f', and 'x', it is the number of digits after the decimal point. +// For 'g' and 'G' it is the total number of digits. A negative precision selects +// the smallest number of decimal digits necessary to identify the value x uniquely +// using x.Prec() mantissa bits. +// The prec value is ignored for the 'b' and 'p' formats. +func (x *Float) Text(format byte, prec int) string { + cap := 10 // TODO(gri) determine a good/better value here + if prec > 0 { + cap += prec + } + return string(x.Append(make([]byte, 0, cap), format, prec)) +} + +// String formats x like x.Text('g', 10). +// (String must be called explicitly, Float.Format does not support %s verb.) +func (x *Float) String() string { + return x.Text('g', 10) +} + +// Append appends to buf the string form of the floating-point number x, +// as generated by x.Text, and returns the extended buffer. +func (x *Float) Append(buf []byte, fmt byte, prec int) []byte { + // sign + if x.neg { + buf = append(buf, '-') + } + + // Inf + if x.form == inf { + if !x.neg { + buf = append(buf, '+') + } + return append(buf, "Inf"...) + } + + // pick off easy formats + switch fmt { + case 'b': + return x.fmtB(buf) + case 'p': + return x.fmtP(buf) + case 'x': + return x.fmtX(buf, prec) + } + + // Algorithm: + // 1) convert Float to multiprecision decimal + // 2) round to desired precision + // 3) read digits out and format + + // 1) convert Float to multiprecision decimal + var d decimal // == 0.0 + if x.form == finite { + // x != 0 + d.init(x.mant, int(x.exp)-x.mant.bitLen()) + } + + // 2) round to desired precision + shortest := false + if prec < 0 { + shortest = true + roundShortest(&d, x) + // Precision for shortest representation mode. + switch fmt { + case 'e', 'E': + prec = len(d.mant) - 1 + case 'f': + prec = max(len(d.mant)-d.exp, 0) + case 'g', 'G': + prec = len(d.mant) + } + } else { + // round appropriately + switch fmt { + case 'e', 'E': + // one digit before and number of digits after decimal point + d.round(1 + prec) + case 'f': + // number of digits before and after decimal point + d.round(d.exp + prec) + case 'g', 'G': + if prec == 0 { + prec = 1 + } + d.round(prec) + } + } + + // 3) read digits out and format + switch fmt { + case 'e', 'E': + return fmtE(buf, fmt, prec, d) + case 'f': + return fmtF(buf, prec, d) + case 'g', 'G': + // trim trailing fractional zeros in %e format + eprec := prec + if eprec > len(d.mant) && len(d.mant) >= d.exp { + eprec = len(d.mant) + } + // %e is used if the exponent from the conversion + // is less than -4 or greater than or equal to the precision. + // If precision was the shortest possible, use eprec = 6 for + // this decision. + if shortest { + eprec = 6 + } + exp := d.exp - 1 + if exp < -4 || exp >= eprec { + if prec > len(d.mant) { + prec = len(d.mant) + } + return fmtE(buf, fmt+'e'-'g', prec-1, d) + } + if prec > d.exp { + prec = len(d.mant) + } + return fmtF(buf, max(prec-d.exp, 0), d) + } + + // unknown format + if x.neg { + buf = buf[:len(buf)-1] // sign was added prematurely - remove it again + } + return append(buf, '%', fmt) +} + +func roundShortest(d *decimal, x *Float) { + // if the mantissa is zero, the number is zero - stop now + if len(d.mant) == 0 { + return + } + + // Approach: All numbers in the interval [x - 1/2ulp, x + 1/2ulp] + // (possibly exclusive) round to x for the given precision of x. + // Compute the lower and upper bound in decimal form and find the + // shortest decimal number d such that lower <= d <= upper. + + // TODO(gri) strconv/ftoa.do describes a shortcut in some cases. + // See if we can use it (in adjusted form) here as well. + + // 1) Compute normalized mantissa mant and exponent exp for x such + // that the lsb of mant corresponds to 1/2 ulp for the precision of + // x (i.e., for mant we want x.prec + 1 bits). + mant := nat(nil).set(x.mant) + exp := int(x.exp) - mant.bitLen() + s := mant.bitLen() - int(x.prec+1) + switch { + case s < 0: + mant = mant.shl(mant, uint(-s)) + case s > 0: + mant = mant.shr(mant, uint(+s)) + } + exp += s + // x = mant * 2**exp with lsb(mant) == 1/2 ulp of x.prec + + // 2) Compute lower bound by subtracting 1/2 ulp. + var lower decimal + var tmp nat + lower.init(tmp.sub(mant, natOne), exp) + + // 3) Compute upper bound by adding 1/2 ulp. + var upper decimal + upper.init(tmp.add(mant, natOne), exp) + + // The upper and lower bounds are possible outputs only if + // the original mantissa is even, so that ToNearestEven rounding + // would round to the original mantissa and not the neighbors. + inclusive := mant[0]&2 == 0 // test bit 1 since original mantissa was shifted by 1 + + // Now we can figure out the minimum number of digits required. + // Walk along until d has distinguished itself from upper and lower. + for i, m := range d.mant { + l := lower.at(i) + u := upper.at(i) + + // Okay to round down (truncate) if lower has a different digit + // or if lower is inclusive and is exactly the result of rounding + // down (i.e., and we have reached the final digit of lower). + okdown := l != m || inclusive && i+1 == len(lower.mant) + + // Okay to round up if upper has a different digit and either upper + // is inclusive or upper is bigger than the result of rounding up. + okup := m != u && (inclusive || m+1 < u || i+1 < len(upper.mant)) + + // If it's okay to do either, then round to the nearest one. + // If it's okay to do only one, do it. + switch { + case okdown && okup: + d.round(i + 1) + return + case okdown: + d.roundDown(i + 1) + return + case okup: + d.roundUp(i + 1) + return + } + } +} + +// %e: d.ddddde±dd +func fmtE(buf []byte, fmt byte, prec int, d decimal) []byte { + // first digit + ch := byte('0') + if len(d.mant) > 0 { + ch = d.mant[0] + } + buf = append(buf, ch) + + // .moredigits + if prec > 0 { + buf = append(buf, '.') + i := 1 + m := min(len(d.mant), prec+1) + if i < m { + buf = append(buf, d.mant[i:m]...) + i = m + } + for ; i <= prec; i++ { + buf = append(buf, '0') + } + } + + // e± + buf = append(buf, fmt) + var exp int64 + if len(d.mant) > 0 { + exp = int64(d.exp) - 1 // -1 because first digit was printed before '.' + } + if exp < 0 { + ch = '-' + exp = -exp + } else { + ch = '+' + } + buf = append(buf, ch) + + // dd...d + if exp < 10 { + buf = append(buf, '0') // at least 2 exponent digits + } + return strconv.AppendInt(buf, exp, 10) +} + +// %f: ddddddd.ddddd +func fmtF(buf []byte, prec int, d decimal) []byte { + // integer, padded with zeros as needed + if d.exp > 0 { + m := min(len(d.mant), d.exp) + buf = append(buf, d.mant[:m]...) + for ; m < d.exp; m++ { + buf = append(buf, '0') + } + } else { + buf = append(buf, '0') + } + + // fraction + if prec > 0 { + buf = append(buf, '.') + for i := 0; i < prec; i++ { + buf = append(buf, d.at(d.exp+i)) + } + } + + return buf +} + +// fmtB appends the string of x in the format mantissa "p" exponent +// with a decimal mantissa and a binary exponent, or 0" if x is zero, +// and returns the extended buffer. +// The mantissa is normalized such that is uses x.Prec() bits in binary +// representation. +// The sign of x is ignored, and x must not be an Inf. +// (The caller handles Inf before invoking fmtB.) +func (x *Float) fmtB(buf []byte) []byte { + if x.form == zero { + return append(buf, '0') + } + + if debugFloat && x.form != finite { + panic("non-finite float") + } + // x != 0 + + // adjust mantissa to use exactly x.prec bits + m := x.mant + switch w := uint32(len(x.mant)) * _W; { + case w < x.prec: + m = nat(nil).shl(m, uint(x.prec-w)) + case w > x.prec: + m = nat(nil).shr(m, uint(w-x.prec)) + } + + buf = append(buf, m.utoa(10)...) + buf = append(buf, 'p') + e := int64(x.exp) - int64(x.prec) + if e >= 0 { + buf = append(buf, '+') + } + return strconv.AppendInt(buf, e, 10) +} + +// fmtX appends the string of x in the format "0x1." mantissa "p" exponent +// with a hexadecimal mantissa and a binary exponent, or "0x0p0" if x is zero, +// and returns the extended buffer. +// A non-zero mantissa is normalized such that 1.0 <= mantissa < 2.0. +// The sign of x is ignored, and x must not be an Inf. +// (The caller handles Inf before invoking fmtX.) +func (x *Float) fmtX(buf []byte, prec int) []byte { + if x.form == zero { + buf = append(buf, "0x0"...) + if prec > 0 { + buf = append(buf, '.') + for i := 0; i < prec; i++ { + buf = append(buf, '0') + } + } + buf = append(buf, "p+00"...) + return buf + } + + if debugFloat && x.form != finite { + panic("non-finite float") + } + + // round mantissa to n bits + var n uint + if prec < 0 { + n = 1 + (x.MinPrec()-1+3)/4*4 // round MinPrec up to 1 mod 4 + } else { + n = 1 + 4*uint(prec) + } + // n%4 == 1 + x = new(Float).SetPrec(n).SetMode(x.mode).Set(x) + + // adjust mantissa to use exactly n bits + m := x.mant + switch w := uint(len(x.mant)) * _W; { + case w < n: + m = nat(nil).shl(m, n-w) + case w > n: + m = nat(nil).shr(m, w-n) + } + exp64 := int64(x.exp) - 1 // avoid wrap-around + + hm := m.utoa(16) + if debugFloat && hm[0] != '1' { + panic("incorrect mantissa: " + string(hm)) + } + buf = append(buf, "0x1"...) + if len(hm) > 1 { + buf = append(buf, '.') + buf = append(buf, hm[1:]...) + } + + buf = append(buf, 'p') + if exp64 >= 0 { + buf = append(buf, '+') + } else { + exp64 = -exp64 + buf = append(buf, '-') + } + // Force at least two exponent digits, to match fmt. + if exp64 < 10 { + buf = append(buf, '0') + } + return strconv.AppendInt(buf, exp64, 10) +} + +// fmtP appends the string of x in the format "0x." mantissa "p" exponent +// with a hexadecimal mantissa and a binary exponent, or "0" if x is zero, +// and returns the extended buffer. +// The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0. +// The sign of x is ignored, and x must not be an Inf. +// (The caller handles Inf before invoking fmtP.) +func (x *Float) fmtP(buf []byte) []byte { + if x.form == zero { + return append(buf, '0') + } + + if debugFloat && x.form != finite { + panic("non-finite float") + } + // x != 0 + + // remove trailing 0 words early + // (no need to convert to hex 0's and trim later) + m := x.mant + i := 0 + for i < len(m) && m[i] == 0 { + i++ + } + m = m[i:] + + buf = append(buf, "0x."...) + buf = append(buf, bytes.TrimRight(m.utoa(16), "0")...) + buf = append(buf, 'p') + if x.exp >= 0 { + buf = append(buf, '+') + } + return strconv.AppendInt(buf, int64(x.exp), 10) +} + +func min(x, y int) int { + if x < y { + return x + } + return y +} + +var _ fmt.Formatter = &floatZero // *Float must implement fmt.Formatter + +// Format implements fmt.Formatter. It accepts all the regular +// formats for floating-point numbers ('b', 'e', 'E', 'f', 'F', +// 'g', 'G', 'x') as well as 'p' and 'v'. See (*Float).Text for the +// interpretation of 'p'. The 'v' format is handled like 'g'. +// Format also supports specification of the minimum precision +// in digits, the output field width, as well as the format flags +// '+' and ' ' for sign control, '0' for space or zero padding, +// and '-' for left or right justification. See the fmt package +// for details. +func (x *Float) Format(s fmt.State, format rune) { + prec, hasPrec := s.Precision() + if !hasPrec { + prec = 6 // default precision for 'e', 'f' + } + + switch format { + case 'e', 'E', 'f', 'b', 'p', 'x': + // nothing to do + case 'F': + // (*Float).Text doesn't support 'F'; handle like 'f' + format = 'f' + case 'v': + // handle like 'g' + format = 'g' + fallthrough + case 'g', 'G': + if !hasPrec { + prec = -1 // default precision for 'g', 'G' + } + default: + fmt.Fprintf(s, "%%!%c(*big.Float=%s)", format, x.String()) + return + } + var buf []byte + buf = x.Append(buf, byte(format), prec) + if len(buf) == 0 { + buf = []byte("?") // should never happen, but don't crash + } + // len(buf) > 0 + + var sign string + switch { + case buf[0] == '-': + sign = "-" + buf = buf[1:] + case buf[0] == '+': + // +Inf + sign = "+" + if s.Flag(' ') { + sign = " " + } + buf = buf[1:] + case s.Flag('+'): + sign = "+" + case s.Flag(' '): + sign = " " + } + + var padding int + if width, hasWidth := s.Width(); hasWidth && width > len(sign)+len(buf) { + padding = width - len(sign) - len(buf) + } + + switch { + case s.Flag('0') && !x.IsInf(): + // 0-padding on left + writeMultiple(s, sign, 1) + writeMultiple(s, "0", padding) + s.Write(buf) + case s.Flag('-'): + // padding on right + writeMultiple(s, sign, 1) + s.Write(buf) + writeMultiple(s, " ", padding) + default: + // padding on left + writeMultiple(s, " ", padding) + writeMultiple(s, sign, 1) + s.Write(buf) + } +} diff --git a/contrib/go/_std_1.18/src/math/big/int.go b/contrib/go/_std_1.18/src/math/big/int.go new file mode 100644 index 0000000000..7647346486 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/int.go @@ -0,0 +1,1218 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements signed multi-precision integers. + +package big + +import ( + "fmt" + "io" + "math/rand" + "strings" +) + +// An Int represents a signed multi-precision integer. +// The zero value for an Int represents the value 0. +// +// Operations always take pointer arguments (*Int) rather +// than Int values, and each unique Int value requires +// its own unique *Int pointer. To "copy" an Int value, +// an existing (or newly allocated) Int must be set to +// a new value using the Int.Set method; shallow copies +// of Ints are not supported and may lead to errors. +type Int struct { + neg bool // sign + abs nat // absolute value of the integer +} + +var intOne = &Int{false, natOne} + +// Sign returns: +// +// -1 if x < 0 +// 0 if x == 0 +// +1 if x > 0 +// +func (x *Int) Sign() int { + if len(x.abs) == 0 { + return 0 + } + if x.neg { + return -1 + } + return 1 +} + +// SetInt64 sets z to x and returns z. +func (z *Int) SetInt64(x int64) *Int { + neg := false + if x < 0 { + neg = true + x = -x + } + z.abs = z.abs.setUint64(uint64(x)) + z.neg = neg + return z +} + +// SetUint64 sets z to x and returns z. +func (z *Int) SetUint64(x uint64) *Int { + z.abs = z.abs.setUint64(x) + z.neg = false + return z +} + +// NewInt allocates and returns a new Int set to x. +func NewInt(x int64) *Int { + return new(Int).SetInt64(x) +} + +// Set sets z to x and returns z. +func (z *Int) Set(x *Int) *Int { + if z != x { + z.abs = z.abs.set(x.abs) + z.neg = x.neg + } + return z +} + +// Bits provides raw (unchecked but fast) access to x by returning its +// absolute value as a little-endian Word slice. The result and x share +// the same underlying array. +// Bits is intended to support implementation of missing low-level Int +// functionality outside this package; it should be avoided otherwise. +func (x *Int) Bits() []Word { + return x.abs +} + +// SetBits provides raw (unchecked but fast) access to z by setting its +// value to abs, interpreted as a little-endian Word slice, and returning +// z. The result and abs share the same underlying array. +// SetBits is intended to support implementation of missing low-level Int +// functionality outside this package; it should be avoided otherwise. +func (z *Int) SetBits(abs []Word) *Int { + z.abs = nat(abs).norm() + z.neg = false + return z +} + +// Abs sets z to |x| (the absolute value of x) and returns z. +func (z *Int) Abs(x *Int) *Int { + z.Set(x) + z.neg = false + return z +} + +// Neg sets z to -x and returns z. +func (z *Int) Neg(x *Int) *Int { + z.Set(x) + z.neg = len(z.abs) > 0 && !z.neg // 0 has no sign + return z +} + +// Add sets z to the sum x+y and returns z. +func (z *Int) Add(x, y *Int) *Int { + neg := x.neg + if x.neg == y.neg { + // x + y == x + y + // (-x) + (-y) == -(x + y) + z.abs = z.abs.add(x.abs, y.abs) + } else { + // x + (-y) == x - y == -(y - x) + // (-x) + y == y - x == -(x - y) + if x.abs.cmp(y.abs) >= 0 { + z.abs = z.abs.sub(x.abs, y.abs) + } else { + neg = !neg + z.abs = z.abs.sub(y.abs, x.abs) + } + } + z.neg = len(z.abs) > 0 && neg // 0 has no sign + return z +} + +// Sub sets z to the difference x-y and returns z. +func (z *Int) Sub(x, y *Int) *Int { + neg := x.neg + if x.neg != y.neg { + // x - (-y) == x + y + // (-x) - y == -(x + y) + z.abs = z.abs.add(x.abs, y.abs) + } else { + // x - y == x - y == -(y - x) + // (-x) - (-y) == y - x == -(x - y) + if x.abs.cmp(y.abs) >= 0 { + z.abs = z.abs.sub(x.abs, y.abs) + } else { + neg = !neg + z.abs = z.abs.sub(y.abs, x.abs) + } + } + z.neg = len(z.abs) > 0 && neg // 0 has no sign + return z +} + +// Mul sets z to the product x*y and returns z. +func (z *Int) Mul(x, y *Int) *Int { + // x * y == x * y + // x * (-y) == -(x * y) + // (-x) * y == -(x * y) + // (-x) * (-y) == x * y + if x == y { + z.abs = z.abs.sqr(x.abs) + z.neg = false + return z + } + z.abs = z.abs.mul(x.abs, y.abs) + z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign + return z +} + +// MulRange sets z to the product of all integers +// in the range [a, b] inclusively and returns z. +// If a > b (empty range), the result is 1. +func (z *Int) MulRange(a, b int64) *Int { + switch { + case a > b: + return z.SetInt64(1) // empty range + case a <= 0 && b >= 0: + return z.SetInt64(0) // range includes 0 + } + // a <= b && (b < 0 || a > 0) + + neg := false + if a < 0 { + neg = (b-a)&1 == 0 + a, b = -b, -a + } + + z.abs = z.abs.mulRange(uint64(a), uint64(b)) + z.neg = neg + return z +} + +// Binomial sets z to the binomial coefficient of (n, k) and returns z. +func (z *Int) Binomial(n, k int64) *Int { + // reduce the number of multiplications by reducing k + if n/2 < k && k <= n { + k = n - k // Binomial(n, k) == Binomial(n, n-k) + } + var a, b Int + a.MulRange(n-k+1, n) + b.MulRange(1, k) + return z.Quo(&a, &b) +} + +// Quo sets z to the quotient x/y for y != 0 and returns z. +// If y == 0, a division-by-zero run-time panic occurs. +// Quo implements truncated division (like Go); see QuoRem for more details. +func (z *Int) Quo(x, y *Int) *Int { + z.abs, _ = z.abs.div(nil, x.abs, y.abs) + z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign + return z +} + +// Rem sets z to the remainder x%y for y != 0 and returns z. +// If y == 0, a division-by-zero run-time panic occurs. +// Rem implements truncated modulus (like Go); see QuoRem for more details. +func (z *Int) Rem(x, y *Int) *Int { + _, z.abs = nat(nil).div(z.abs, x.abs, y.abs) + z.neg = len(z.abs) > 0 && x.neg // 0 has no sign + return z +} + +// QuoRem sets z to the quotient x/y and r to the remainder x%y +// and returns the pair (z, r) for y != 0. +// If y == 0, a division-by-zero run-time panic occurs. +// +// QuoRem implements T-division and modulus (like Go): +// +// q = x/y with the result truncated to zero +// r = x - y*q +// +// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.) +// See DivMod for Euclidean division and modulus (unlike Go). +// +func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) { + z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs) + z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign + return z, r +} + +// Div sets z to the quotient x/y for y != 0 and returns z. +// If y == 0, a division-by-zero run-time panic occurs. +// Div implements Euclidean division (unlike Go); see DivMod for more details. +func (z *Int) Div(x, y *Int) *Int { + y_neg := y.neg // z may be an alias for y + var r Int + z.QuoRem(x, y, &r) + if r.neg { + if y_neg { + z.Add(z, intOne) + } else { + z.Sub(z, intOne) + } + } + return z +} + +// Mod sets z to the modulus x%y for y != 0 and returns z. +// If y == 0, a division-by-zero run-time panic occurs. +// Mod implements Euclidean modulus (unlike Go); see DivMod for more details. +func (z *Int) Mod(x, y *Int) *Int { + y0 := y // save y + if z == y || alias(z.abs, y.abs) { + y0 = new(Int).Set(y) + } + var q Int + q.QuoRem(x, y, z) + if z.neg { + if y0.neg { + z.Sub(z, y0) + } else { + z.Add(z, y0) + } + } + return z +} + +// DivMod sets z to the quotient x div y and m to the modulus x mod y +// and returns the pair (z, m) for y != 0. +// If y == 0, a division-by-zero run-time panic occurs. +// +// DivMod implements Euclidean division and modulus (unlike Go): +// +// q = x div y such that +// m = x - y*q with 0 <= m < |y| +// +// (See Raymond T. Boute, ``The Euclidean definition of the functions +// div and mod''. ACM Transactions on Programming Languages and +// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992. +// ACM press.) +// See QuoRem for T-division and modulus (like Go). +// +func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) { + y0 := y // save y + if z == y || alias(z.abs, y.abs) { + y0 = new(Int).Set(y) + } + z.QuoRem(x, y, m) + if m.neg { + if y0.neg { + z.Add(z, intOne) + m.Sub(m, y0) + } else { + z.Sub(z, intOne) + m.Add(m, y0) + } + } + return z, m +} + +// Cmp compares x and y and returns: +// +// -1 if x < y +// 0 if x == y +// +1 if x > y +// +func (x *Int) Cmp(y *Int) (r int) { + // x cmp y == x cmp y + // x cmp (-y) == x + // (-x) cmp y == y + // (-x) cmp (-y) == -(x cmp y) + switch { + case x == y: + // nothing to do + case x.neg == y.neg: + r = x.abs.cmp(y.abs) + if x.neg { + r = -r + } + case x.neg: + r = -1 + default: + r = 1 + } + return +} + +// CmpAbs compares the absolute values of x and y and returns: +// +// -1 if |x| < |y| +// 0 if |x| == |y| +// +1 if |x| > |y| +// +func (x *Int) CmpAbs(y *Int) int { + return x.abs.cmp(y.abs) +} + +// low32 returns the least significant 32 bits of x. +func low32(x nat) uint32 { + if len(x) == 0 { + return 0 + } + return uint32(x[0]) +} + +// low64 returns the least significant 64 bits of x. +func low64(x nat) uint64 { + if len(x) == 0 { + return 0 + } + v := uint64(x[0]) + if _W == 32 && len(x) > 1 { + return uint64(x[1])<<32 | v + } + return v +} + +// Int64 returns the int64 representation of x. +// If x cannot be represented in an int64, the result is undefined. +func (x *Int) Int64() int64 { + v := int64(low64(x.abs)) + if x.neg { + v = -v + } + return v +} + +// Uint64 returns the uint64 representation of x. +// If x cannot be represented in a uint64, the result is undefined. +func (x *Int) Uint64() uint64 { + return low64(x.abs) +} + +// IsInt64 reports whether x can be represented as an int64. +func (x *Int) IsInt64() bool { + if len(x.abs) <= 64/_W { + w := int64(low64(x.abs)) + return w >= 0 || x.neg && w == -w + } + return false +} + +// IsUint64 reports whether x can be represented as a uint64. +func (x *Int) IsUint64() bool { + return !x.neg && len(x.abs) <= 64/_W +} + +// SetString sets z to the value of s, interpreted in the given base, +// and returns z and a boolean indicating success. The entire string +// (not just a prefix) must be valid for success. If SetString fails, +// the value of z is undefined but the returned value is nil. +// +// The base argument must be 0 or a value between 2 and MaxBase. +// For base 0, the number prefix determines the actual base: A prefix of +// ``0b'' or ``0B'' selects base 2, ``0'', ``0o'' or ``0O'' selects base 8, +// and ``0x'' or ``0X'' selects base 16. Otherwise, the selected base is 10 +// and no prefix is accepted. +// +// For bases <= 36, lower and upper case letters are considered the same: +// The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35. +// For bases > 36, the upper case letters 'A' to 'Z' represent the digit +// values 36 to 61. +// +// For base 0, an underscore character ``_'' may appear between a base +// prefix and an adjacent digit, and between successive digits; such +// underscores do not change the value of the number. +// Incorrect placement of underscores is reported as an error if there +// are no other errors. If base != 0, underscores are not recognized +// and act like any other character that is not a valid digit. +// +func (z *Int) SetString(s string, base int) (*Int, bool) { + return z.setFromScanner(strings.NewReader(s), base) +} + +// setFromScanner implements SetString given an io.ByteScanner. +// For documentation see comments of SetString. +func (z *Int) setFromScanner(r io.ByteScanner, base int) (*Int, bool) { + if _, _, err := z.scan(r, base); err != nil { + return nil, false + } + // entire content must have been consumed + if _, err := r.ReadByte(); err != io.EOF { + return nil, false + } + return z, true // err == io.EOF => scan consumed all content of r +} + +// SetBytes interprets buf as the bytes of a big-endian unsigned +// integer, sets z to that value, and returns z. +func (z *Int) SetBytes(buf []byte) *Int { + z.abs = z.abs.setBytes(buf) + z.neg = false + return z +} + +// Bytes returns the absolute value of x as a big-endian byte slice. +// +// To use a fixed length slice, or a preallocated one, use FillBytes. +func (x *Int) Bytes() []byte { + buf := make([]byte, len(x.abs)*_S) + return buf[x.abs.bytes(buf):] +} + +// FillBytes sets buf to the absolute value of x, storing it as a zero-extended +// big-endian byte slice, and returns buf. +// +// If the absolute value of x doesn't fit in buf, FillBytes will panic. +func (x *Int) FillBytes(buf []byte) []byte { + // Clear whole buffer. (This gets optimized into a memclr.) + for i := range buf { + buf[i] = 0 + } + x.abs.bytes(buf) + return buf +} + +// BitLen returns the length of the absolute value of x in bits. +// The bit length of 0 is 0. +func (x *Int) BitLen() int { + return x.abs.bitLen() +} + +// TrailingZeroBits returns the number of consecutive least significant zero +// bits of |x|. +func (x *Int) TrailingZeroBits() uint { + return x.abs.trailingZeroBits() +} + +// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z. +// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m != 0, y < 0, +// and x and m are not relatively prime, z is unchanged and nil is returned. +// +// Modular exponentiation of inputs of a particular size is not a +// cryptographically constant-time operation. +func (z *Int) Exp(x, y, m *Int) *Int { + // See Knuth, volume 2, section 4.6.3. + xWords := x.abs + if y.neg { + if m == nil || len(m.abs) == 0 { + return z.SetInt64(1) + } + // for y < 0: x**y mod m == (x**(-1))**|y| mod m + inverse := new(Int).ModInverse(x, m) + if inverse == nil { + return nil + } + xWords = inverse.abs + } + yWords := y.abs + + var mWords nat + if m != nil { + mWords = m.abs // m.abs may be nil for m == 0 + } + + z.abs = z.abs.expNN(xWords, yWords, mWords) + z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign + if z.neg && len(mWords) > 0 { + // make modulus result positive + z.abs = z.abs.sub(mWords, z.abs) // z == x**y mod |m| && 0 <= z < |m| + z.neg = false + } + + return z +} + +// GCD sets z to the greatest common divisor of a and b and returns z. +// If x or y are not nil, GCD sets their value such that z = a*x + b*y. +// +// a and b may be positive, zero or negative. (Before Go 1.14 both had +// to be > 0.) Regardless of the signs of a and b, z is always >= 0. +// +// If a == b == 0, GCD sets z = x = y = 0. +// +// If a == 0 and b != 0, GCD sets z = |b|, x = 0, y = sign(b) * 1. +// +// If a != 0 and b == 0, GCD sets z = |a|, x = sign(a) * 1, y = 0. +func (z *Int) GCD(x, y, a, b *Int) *Int { + if len(a.abs) == 0 || len(b.abs) == 0 { + lenA, lenB, negA, negB := len(a.abs), len(b.abs), a.neg, b.neg + if lenA == 0 { + z.Set(b) + } else { + z.Set(a) + } + z.neg = false + if x != nil { + if lenA == 0 { + x.SetUint64(0) + } else { + x.SetUint64(1) + x.neg = negA + } + } + if y != nil { + if lenB == 0 { + y.SetUint64(0) + } else { + y.SetUint64(1) + y.neg = negB + } + } + return z + } + + return z.lehmerGCD(x, y, a, b) +} + +// lehmerSimulate attempts to simulate several Euclidean update steps +// using the leading digits of A and B. It returns u0, u1, v0, v1 +// such that A and B can be updated as: +// A = u0*A + v0*B +// B = u1*A + v1*B +// Requirements: A >= B and len(B.abs) >= 2 +// Since we are calculating with full words to avoid overflow, +// we use 'even' to track the sign of the cosequences. +// For even iterations: u0, v1 >= 0 && u1, v0 <= 0 +// For odd iterations: u0, v1 <= 0 && u1, v0 >= 0 +func lehmerSimulate(A, B *Int) (u0, u1, v0, v1 Word, even bool) { + // initialize the digits + var a1, a2, u2, v2 Word + + m := len(B.abs) // m >= 2 + n := len(A.abs) // n >= m >= 2 + + // extract the top Word of bits from A and B + h := nlz(A.abs[n-1]) + a1 = A.abs[n-1]<<h | A.abs[n-2]>>(_W-h) + // B may have implicit zero words in the high bits if the lengths differ + switch { + case n == m: + a2 = B.abs[n-1]<<h | B.abs[n-2]>>(_W-h) + case n == m+1: + a2 = B.abs[n-2] >> (_W - h) + default: + a2 = 0 + } + + // Since we are calculating with full words to avoid overflow, + // we use 'even' to track the sign of the cosequences. + // For even iterations: u0, v1 >= 0 && u1, v0 <= 0 + // For odd iterations: u0, v1 <= 0 && u1, v0 >= 0 + // The first iteration starts with k=1 (odd). + even = false + // variables to track the cosequences + u0, u1, u2 = 0, 1, 0 + v0, v1, v2 = 0, 0, 1 + + // Calculate the quotient and cosequences using Collins' stopping condition. + // Note that overflow of a Word is not possible when computing the remainder + // sequence and cosequences since the cosequence size is bounded by the input size. + // See section 4.2 of Jebelean for details. + for a2 >= v2 && a1-a2 >= v1+v2 { + q, r := a1/a2, a1%a2 + a1, a2 = a2, r + u0, u1, u2 = u1, u2, u1+q*u2 + v0, v1, v2 = v1, v2, v1+q*v2 + even = !even + } + return +} + +// lehmerUpdate updates the inputs A and B such that: +// A = u0*A + v0*B +// B = u1*A + v1*B +// where the signs of u0, u1, v0, v1 are given by even +// For even == true: u0, v1 >= 0 && u1, v0 <= 0 +// For even == false: u0, v1 <= 0 && u1, v0 >= 0 +// q, r, s, t are temporary variables to avoid allocations in the multiplication +func lehmerUpdate(A, B, q, r, s, t *Int, u0, u1, v0, v1 Word, even bool) { + + t.abs = t.abs.setWord(u0) + s.abs = s.abs.setWord(v0) + t.neg = !even + s.neg = even + + t.Mul(A, t) + s.Mul(B, s) + + r.abs = r.abs.setWord(u1) + q.abs = q.abs.setWord(v1) + r.neg = even + q.neg = !even + + r.Mul(A, r) + q.Mul(B, q) + + A.Add(t, s) + B.Add(r, q) +} + +// euclidUpdate performs a single step of the Euclidean GCD algorithm +// if extended is true, it also updates the cosequence Ua, Ub +func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) { + q, r = q.QuoRem(A, B, r) + + *A, *B, *r = *B, *r, *A + + if extended { + // Ua, Ub = Ub, Ua - q*Ub + t.Set(Ub) + s.Mul(Ub, q) + Ub.Sub(Ua, s) + Ua.Set(t) + } +} + +// lehmerGCD sets z to the greatest common divisor of a and b, +// which both must be != 0, and returns z. +// If x or y are not nil, their values are set such that z = a*x + b*y. +// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm L. +// This implementation uses the improved condition by Collins requiring only one +// quotient and avoiding the possibility of single Word overflow. +// See Jebelean, "Improving the multiprecision Euclidean algorithm", +// Design and Implementation of Symbolic Computation Systems, pp 45-58. +// The cosequences are updated according to Algorithm 10.45 from +// Cohen et al. "Handbook of Elliptic and Hyperelliptic Curve Cryptography" pp 192. +func (z *Int) lehmerGCD(x, y, a, b *Int) *Int { + var A, B, Ua, Ub *Int + + A = new(Int).Abs(a) + B = new(Int).Abs(b) + + extended := x != nil || y != nil + + if extended { + // Ua (Ub) tracks how many times input a has been accumulated into A (B). + Ua = new(Int).SetInt64(1) + Ub = new(Int) + } + + // temp variables for multiprecision update + q := new(Int) + r := new(Int) + s := new(Int) + t := new(Int) + + // ensure A >= B + if A.abs.cmp(B.abs) < 0 { + A, B = B, A + Ub, Ua = Ua, Ub + } + + // loop invariant A >= B + for len(B.abs) > 1 { + // Attempt to calculate in single-precision using leading words of A and B. + u0, u1, v0, v1, even := lehmerSimulate(A, B) + + // multiprecision Step + if v0 != 0 { + // Simulate the effect of the single-precision steps using the cosequences. + // A = u0*A + v0*B + // B = u1*A + v1*B + lehmerUpdate(A, B, q, r, s, t, u0, u1, v0, v1, even) + + if extended { + // Ua = u0*Ua + v0*Ub + // Ub = u1*Ua + v1*Ub + lehmerUpdate(Ua, Ub, q, r, s, t, u0, u1, v0, v1, even) + } + + } else { + // Single-digit calculations failed to simulate any quotients. + // Do a standard Euclidean step. + euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended) + } + } + + if len(B.abs) > 0 { + // extended Euclidean algorithm base case if B is a single Word + if len(A.abs) > 1 { + // A is longer than a single Word, so one update is needed. + euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended) + } + if len(B.abs) > 0 { + // A and B are both a single Word. + aWord, bWord := A.abs[0], B.abs[0] + if extended { + var ua, ub, va, vb Word + ua, ub = 1, 0 + va, vb = 0, 1 + even := true + for bWord != 0 { + q, r := aWord/bWord, aWord%bWord + aWord, bWord = bWord, r + ua, ub = ub, ua+q*ub + va, vb = vb, va+q*vb + even = !even + } + + t.abs = t.abs.setWord(ua) + s.abs = s.abs.setWord(va) + t.neg = !even + s.neg = even + + t.Mul(Ua, t) + s.Mul(Ub, s) + + Ua.Add(t, s) + } else { + for bWord != 0 { + aWord, bWord = bWord, aWord%bWord + } + } + A.abs[0] = aWord + } + } + negA := a.neg + if y != nil { + // avoid aliasing b needed in the division below + if y == b { + B.Set(b) + } else { + B = b + } + // y = (z - a*x)/b + y.Mul(a, Ua) // y can safely alias a + if negA { + y.neg = !y.neg + } + y.Sub(A, y) + y.Div(y, B) + } + + if x != nil { + *x = *Ua + if negA { + x.neg = !x.neg + } + } + + *z = *A + + return z +} + +// Rand sets z to a pseudo-random number in [0, n) and returns z. +// +// As this uses the math/rand package, it must not be used for +// security-sensitive work. Use crypto/rand.Int instead. +func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { + z.neg = false + if n.neg || len(n.abs) == 0 { + z.abs = nil + return z + } + z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen()) + return z +} + +// ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ +// and returns z. If g and n are not relatively prime, g has no multiplicative +// inverse in the ring ℤ/nℤ. In this case, z is unchanged and the return value +// is nil. +func (z *Int) ModInverse(g, n *Int) *Int { + // GCD expects parameters a and b to be > 0. + if n.neg { + var n2 Int + n = n2.Neg(n) + } + if g.neg { + var g2 Int + g = g2.Mod(g, n) + } + var d, x Int + d.GCD(&x, nil, g, n) + + // if and only if d==1, g and n are relatively prime + if d.Cmp(intOne) != 0 { + return nil + } + + // x and y are such that g*x + n*y = 1, therefore x is the inverse element, + // but it may be negative, so convert to the range 0 <= z < |n| + if x.neg { + z.Add(&x, n) + } else { + z.Set(&x) + } + return z +} + +// Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0. +// The y argument must be an odd integer. +func Jacobi(x, y *Int) int { + if len(y.abs) == 0 || y.abs[0]&1 == 0 { + panic(fmt.Sprintf("big: invalid 2nd argument to Int.Jacobi: need odd integer but got %s", y)) + } + + // We use the formulation described in chapter 2, section 2.4, + // "The Yacas Book of Algorithms": + // http://yacas.sourceforge.net/Algo.book.pdf + + var a, b, c Int + a.Set(x) + b.Set(y) + j := 1 + + if b.neg { + if a.neg { + j = -1 + } + b.neg = false + } + + for { + if b.Cmp(intOne) == 0 { + return j + } + if len(a.abs) == 0 { + return 0 + } + a.Mod(&a, &b) + if len(a.abs) == 0 { + return 0 + } + // a > 0 + + // handle factors of 2 in 'a' + s := a.abs.trailingZeroBits() + if s&1 != 0 { + bmod8 := b.abs[0] & 7 + if bmod8 == 3 || bmod8 == 5 { + j = -j + } + } + c.Rsh(&a, s) // a = 2^s*c + + // swap numerator and denominator + if b.abs[0]&3 == 3 && c.abs[0]&3 == 3 { + j = -j + } + a.Set(&b) + b.Set(&c) + } +} + +// modSqrt3Mod4 uses the identity +// (a^((p+1)/4))^2 mod p +// == u^(p+1) mod p +// == u^2 mod p +// to calculate the square root of any quadratic residue mod p quickly for 3 +// mod 4 primes. +func (z *Int) modSqrt3Mod4Prime(x, p *Int) *Int { + e := new(Int).Add(p, intOne) // e = p + 1 + e.Rsh(e, 2) // e = (p + 1) / 4 + z.Exp(x, e, p) // z = x^e mod p + return z +} + +// modSqrt5Mod8 uses Atkin's observation that 2 is not a square mod p +// alpha == (2*a)^((p-5)/8) mod p +// beta == 2*a*alpha^2 mod p is a square root of -1 +// b == a*alpha*(beta-1) mod p is a square root of a +// to calculate the square root of any quadratic residue mod p quickly for 5 +// mod 8 primes. +func (z *Int) modSqrt5Mod8Prime(x, p *Int) *Int { + // p == 5 mod 8 implies p = e*8 + 5 + // e is the quotient and 5 the remainder on division by 8 + e := new(Int).Rsh(p, 3) // e = (p - 5) / 8 + tx := new(Int).Lsh(x, 1) // tx = 2*x + alpha := new(Int).Exp(tx, e, p) + beta := new(Int).Mul(alpha, alpha) + beta.Mod(beta, p) + beta.Mul(beta, tx) + beta.Mod(beta, p) + beta.Sub(beta, intOne) + beta.Mul(beta, x) + beta.Mod(beta, p) + beta.Mul(beta, alpha) + z.Mod(beta, p) + return z +} + +// modSqrtTonelliShanks uses the Tonelli-Shanks algorithm to find the square +// root of a quadratic residue modulo any prime. +func (z *Int) modSqrtTonelliShanks(x, p *Int) *Int { + // Break p-1 into s*2^e such that s is odd. + var s Int + s.Sub(p, intOne) + e := s.abs.trailingZeroBits() + s.Rsh(&s, e) + + // find some non-square n + var n Int + n.SetInt64(2) + for Jacobi(&n, p) != -1 { + n.Add(&n, intOne) + } + + // Core of the Tonelli-Shanks algorithm. Follows the description in + // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra + // Brown: + // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf + var y, b, g, t Int + y.Add(&s, intOne) + y.Rsh(&y, 1) + y.Exp(x, &y, p) // y = x^((s+1)/2) + b.Exp(x, &s, p) // b = x^s + g.Exp(&n, &s, p) // g = n^s + r := e + for { + // find the least m such that ord_p(b) = 2^m + var m uint + t.Set(&b) + for t.Cmp(intOne) != 0 { + t.Mul(&t, &t).Mod(&t, p) + m++ + } + + if m == 0 { + return z.Set(&y) + } + + t.SetInt64(0).SetBit(&t, int(r-m-1), 1).Exp(&g, &t, p) + // t = g^(2^(r-m-1)) mod p + g.Mul(&t, &t).Mod(&g, p) // g = g^(2^(r-m)) mod p + y.Mul(&y, &t).Mod(&y, p) + b.Mul(&b, &g).Mod(&b, p) + r = m + } +} + +// ModSqrt sets z to a square root of x mod p if such a square root exists, and +// returns z. The modulus p must be an odd prime. If x is not a square mod p, +// ModSqrt leaves z unchanged and returns nil. This function panics if p is +// not an odd integer. +func (z *Int) ModSqrt(x, p *Int) *Int { + switch Jacobi(x, p) { + case -1: + return nil // x is not a square mod p + case 0: + return z.SetInt64(0) // sqrt(0) mod p = 0 + case 1: + break + } + if x.neg || x.Cmp(p) >= 0 { // ensure 0 <= x < p + x = new(Int).Mod(x, p) + } + + switch { + case p.abs[0]%4 == 3: + // Check whether p is 3 mod 4, and if so, use the faster algorithm. + return z.modSqrt3Mod4Prime(x, p) + case p.abs[0]%8 == 5: + // Check whether p is 5 mod 8, use Atkin's algorithm. + return z.modSqrt5Mod8Prime(x, p) + default: + // Otherwise, use Tonelli-Shanks. + return z.modSqrtTonelliShanks(x, p) + } +} + +// Lsh sets z = x << n and returns z. +func (z *Int) Lsh(x *Int, n uint) *Int { + z.abs = z.abs.shl(x.abs, n) + z.neg = x.neg + return z +} + +// Rsh sets z = x >> n and returns z. +func (z *Int) Rsh(x *Int, n uint) *Int { + if x.neg { + // (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1) + t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0 + t = t.shr(t, n) + z.abs = t.add(t, natOne) + z.neg = true // z cannot be zero if x is negative + return z + } + + z.abs = z.abs.shr(x.abs, n) + z.neg = false + return z +} + +// Bit returns the value of the i'th bit of x. That is, it +// returns (x>>i)&1. The bit index i must be >= 0. +func (x *Int) Bit(i int) uint { + if i == 0 { + // optimization for common case: odd/even test of x + if len(x.abs) > 0 { + return uint(x.abs[0] & 1) // bit 0 is same for -x + } + return 0 + } + if i < 0 { + panic("negative bit index") + } + if x.neg { + t := nat(nil).sub(x.abs, natOne) + return t.bit(uint(i)) ^ 1 + } + + return x.abs.bit(uint(i)) +} + +// SetBit sets z to x, with x's i'th bit set to b (0 or 1). +// That is, if b is 1 SetBit sets z = x | (1 << i); +// if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1, +// SetBit will panic. +func (z *Int) SetBit(x *Int, i int, b uint) *Int { + if i < 0 { + panic("negative bit index") + } + if x.neg { + t := z.abs.sub(x.abs, natOne) + t = t.setBit(t, uint(i), b^1) + z.abs = t.add(t, natOne) + z.neg = len(z.abs) > 0 + return z + } + z.abs = z.abs.setBit(x.abs, uint(i), b) + z.neg = false + return z +} + +// And sets z = x & y and returns z. +func (z *Int) And(x, y *Int) *Int { + if x.neg == y.neg { + if x.neg { + // (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1) + x1 := nat(nil).sub(x.abs, natOne) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.add(z.abs.or(x1, y1), natOne) + z.neg = true // z cannot be zero if x and y are negative + return z + } + + // x & y == x & y + z.abs = z.abs.and(x.abs, y.abs) + z.neg = false + return z + } + + // x.neg != y.neg + if x.neg { + x, y = y, x // & is symmetric + } + + // x & (-y) == x & ^(y-1) == x &^ (y-1) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.andNot(x.abs, y1) + z.neg = false + return z +} + +// AndNot sets z = x &^ y and returns z. +func (z *Int) AndNot(x, y *Int) *Int { + if x.neg == y.neg { + if x.neg { + // (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1) + x1 := nat(nil).sub(x.abs, natOne) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.andNot(y1, x1) + z.neg = false + return z + } + + // x &^ y == x &^ y + z.abs = z.abs.andNot(x.abs, y.abs) + z.neg = false + return z + } + + if x.neg { + // (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1) + x1 := nat(nil).sub(x.abs, natOne) + z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne) + z.neg = true // z cannot be zero if x is negative and y is positive + return z + } + + // x &^ (-y) == x &^ ^(y-1) == x & (y-1) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.and(x.abs, y1) + z.neg = false + return z +} + +// Or sets z = x | y and returns z. +func (z *Int) Or(x, y *Int) *Int { + if x.neg == y.neg { + if x.neg { + // (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1) + x1 := nat(nil).sub(x.abs, natOne) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.add(z.abs.and(x1, y1), natOne) + z.neg = true // z cannot be zero if x and y are negative + return z + } + + // x | y == x | y + z.abs = z.abs.or(x.abs, y.abs) + z.neg = false + return z + } + + // x.neg != y.neg + if x.neg { + x, y = y, x // | is symmetric + } + + // x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne) + z.neg = true // z cannot be zero if one of x or y is negative + return z +} + +// Xor sets z = x ^ y and returns z. +func (z *Int) Xor(x, y *Int) *Int { + if x.neg == y.neg { + if x.neg { + // (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1) + x1 := nat(nil).sub(x.abs, natOne) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.xor(x1, y1) + z.neg = false + return z + } + + // x ^ y == x ^ y + z.abs = z.abs.xor(x.abs, y.abs) + z.neg = false + return z + } + + // x.neg != y.neg + if x.neg { + x, y = y, x // ^ is symmetric + } + + // x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1) + y1 := nat(nil).sub(y.abs, natOne) + z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne) + z.neg = true // z cannot be zero if only one of x or y is negative + return z +} + +// Not sets z = ^x and returns z. +func (z *Int) Not(x *Int) *Int { + if x.neg { + // ^(-x) == ^(^(x-1)) == x-1 + z.abs = z.abs.sub(x.abs, natOne) + z.neg = false + return z + } + + // ^x == -x-1 == -(x+1) + z.abs = z.abs.add(x.abs, natOne) + z.neg = true // z cannot be zero if x is positive + return z +} + +// Sqrt sets z to ⌊√x⌋, the largest integer such that z² ≤ x, and returns z. +// It panics if x is negative. +func (z *Int) Sqrt(x *Int) *Int { + if x.neg { + panic("square root of negative number") + } + z.neg = false + z.abs = z.abs.sqrt(x.abs) + return z +} diff --git a/contrib/go/_std_1.18/src/math/big/intconv.go b/contrib/go/_std_1.18/src/math/big/intconv.go new file mode 100644 index 0000000000..0567284105 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/intconv.go @@ -0,0 +1,257 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements int-to-string conversion functions. + +package big + +import ( + "errors" + "fmt" + "io" +) + +// Text returns the string representation of x in the given base. +// Base must be between 2 and 62, inclusive. The result uses the +// lower-case letters 'a' to 'z' for digit values 10 to 35, and +// the upper-case letters 'A' to 'Z' for digit values 36 to 61. +// No prefix (such as "0x") is added to the string. If x is a nil +// pointer it returns "<nil>". +func (x *Int) Text(base int) string { + if x == nil { + return "<nil>" + } + return string(x.abs.itoa(x.neg, base)) +} + +// Append appends the string representation of x, as generated by +// x.Text(base), to buf and returns the extended buffer. +func (x *Int) Append(buf []byte, base int) []byte { + if x == nil { + return append(buf, "<nil>"...) + } + return append(buf, x.abs.itoa(x.neg, base)...) +} + +// String returns the decimal representation of x as generated by +// x.Text(10). +func (x *Int) String() string { + return x.Text(10) +} + +// write count copies of text to s +func writeMultiple(s fmt.State, text string, count int) { + if len(text) > 0 { + b := []byte(text) + for ; count > 0; count-- { + s.Write(b) + } + } +} + +var _ fmt.Formatter = intOne // *Int must implement fmt.Formatter + +// Format implements fmt.Formatter. It accepts the formats +// 'b' (binary), 'o' (octal with 0 prefix), 'O' (octal with 0o prefix), +// 'd' (decimal), 'x' (lowercase hexadecimal), and +// 'X' (uppercase hexadecimal). +// Also supported are the full suite of package fmt's format +// flags for integral types, including '+' and ' ' for sign +// control, '#' for leading zero in octal and for hexadecimal, +// a leading "0x" or "0X" for "%#x" and "%#X" respectively, +// specification of minimum digits precision, output field +// width, space or zero padding, and '-' for left or right +// justification. +// +func (x *Int) Format(s fmt.State, ch rune) { + // determine base + var base int + switch ch { + case 'b': + base = 2 + case 'o', 'O': + base = 8 + case 'd', 's', 'v': + base = 10 + case 'x', 'X': + base = 16 + default: + // unknown format + fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String()) + return + } + + if x == nil { + fmt.Fprint(s, "<nil>") + return + } + + // determine sign character + sign := "" + switch { + case x.neg: + sign = "-" + case s.Flag('+'): // supersedes ' ' when both specified + sign = "+" + case s.Flag(' '): + sign = " " + } + + // determine prefix characters for indicating output base + prefix := "" + if s.Flag('#') { + switch ch { + case 'b': // binary + prefix = "0b" + case 'o': // octal + prefix = "0" + case 'x': // hexadecimal + prefix = "0x" + case 'X': + prefix = "0X" + } + } + if ch == 'O' { + prefix = "0o" + } + + digits := x.abs.utoa(base) + if ch == 'X' { + // faster than bytes.ToUpper + for i, d := range digits { + if 'a' <= d && d <= 'z' { + digits[i] = 'A' + (d - 'a') + } + } + } + + // number of characters for the three classes of number padding + var left int // space characters to left of digits for right justification ("%8d") + var zeros int // zero characters (actually cs[0]) as left-most digits ("%.8d") + var right int // space characters to right of digits for left justification ("%-8d") + + // determine number padding from precision: the least number of digits to output + precision, precisionSet := s.Precision() + if precisionSet { + switch { + case len(digits) < precision: + zeros = precision - len(digits) // count of zero padding + case len(digits) == 1 && digits[0] == '0' && precision == 0: + return // print nothing if zero value (x == 0) and zero precision ("." or ".0") + } + } + + // determine field pad from width: the least number of characters to output + length := len(sign) + len(prefix) + zeros + len(digits) + if width, widthSet := s.Width(); widthSet && length < width { // pad as specified + switch d := width - length; { + case s.Flag('-'): + // pad on the right with spaces; supersedes '0' when both specified + right = d + case s.Flag('0') && !precisionSet: + // pad with zeros unless precision also specified + zeros = d + default: + // pad on the left with spaces + left = d + } + } + + // print number as [left pad][sign][prefix][zero pad][digits][right pad] + writeMultiple(s, " ", left) + writeMultiple(s, sign, 1) + writeMultiple(s, prefix, 1) + writeMultiple(s, "0", zeros) + s.Write(digits) + writeMultiple(s, " ", right) +} + +// scan sets z to the integer value corresponding to the longest possible prefix +// read from r representing a signed integer number in a given conversion base. +// It returns z, the actual conversion base used, and an error, if any. In the +// error case, the value of z is undefined but the returned value is nil. The +// syntax follows the syntax of integer literals in Go. +// +// The base argument must be 0 or a value from 2 through MaxBase. If the base +// is 0, the string prefix determines the actual conversion base. A prefix of +// ``0b'' or ``0B'' selects base 2; a ``0'', ``0o'', or ``0O'' prefix selects +// base 8, and a ``0x'' or ``0X'' prefix selects base 16. Otherwise the selected +// base is 10. +// +func (z *Int) scan(r io.ByteScanner, base int) (*Int, int, error) { + // determine sign + neg, err := scanSign(r) + if err != nil { + return nil, 0, err + } + + // determine mantissa + z.abs, base, _, err = z.abs.scan(r, base, false) + if err != nil { + return nil, base, err + } + z.neg = len(z.abs) > 0 && neg // 0 has no sign + + return z, base, nil +} + +func scanSign(r io.ByteScanner) (neg bool, err error) { + var ch byte + if ch, err = r.ReadByte(); err != nil { + return false, err + } + switch ch { + case '-': + neg = true + case '+': + // nothing to do + default: + r.UnreadByte() + } + return +} + +// byteReader is a local wrapper around fmt.ScanState; +// it implements the ByteReader interface. +type byteReader struct { + fmt.ScanState +} + +func (r byteReader) ReadByte() (byte, error) { + ch, size, err := r.ReadRune() + if size != 1 && err == nil { + err = fmt.Errorf("invalid rune %#U", ch) + } + return byte(ch), err +} + +func (r byteReader) UnreadByte() error { + return r.UnreadRune() +} + +var _ fmt.Scanner = intOne // *Int must implement fmt.Scanner + +// Scan is a support routine for fmt.Scanner; it sets z to the value of +// the scanned number. It accepts the formats 'b' (binary), 'o' (octal), +// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal). +func (z *Int) Scan(s fmt.ScanState, ch rune) error { + s.SkipSpace() // skip leading space characters + base := 0 + switch ch { + case 'b': + base = 2 + case 'o': + base = 8 + case 'd': + base = 10 + case 'x', 'X': + base = 16 + case 's', 'v': + // let scan determine the base + default: + return errors.New("Int.Scan: invalid verb") + } + _, _, err := z.scan(byteReader{s}, base) + return err +} diff --git a/contrib/go/_std_1.18/src/math/big/intmarsh.go b/contrib/go/_std_1.18/src/math/big/intmarsh.go new file mode 100644 index 0000000000..c1422e2710 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/intmarsh.go @@ -0,0 +1,80 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements encoding/decoding of Ints. + +package big + +import ( + "bytes" + "fmt" +) + +// Gob codec version. Permits backward-compatible changes to the encoding. +const intGobVersion byte = 1 + +// GobEncode implements the gob.GobEncoder interface. +func (x *Int) GobEncode() ([]byte, error) { + if x == nil { + return nil, nil + } + buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit + i := x.abs.bytes(buf) - 1 // i >= 0 + b := intGobVersion << 1 // make space for sign bit + if x.neg { + b |= 1 + } + buf[i] = b + return buf[i:], nil +} + +// GobDecode implements the gob.GobDecoder interface. +func (z *Int) GobDecode(buf []byte) error { + if len(buf) == 0 { + // Other side sent a nil or default value. + *z = Int{} + return nil + } + b := buf[0] + if b>>1 != intGobVersion { + return fmt.Errorf("Int.GobDecode: encoding version %d not supported", b>>1) + } + z.neg = b&1 != 0 + z.abs = z.abs.setBytes(buf[1:]) + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (x *Int) MarshalText() (text []byte, err error) { + if x == nil { + return []byte("<nil>"), nil + } + return x.abs.itoa(x.neg, 10), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (z *Int) UnmarshalText(text []byte) error { + if _, ok := z.setFromScanner(bytes.NewReader(text), 0); !ok { + return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text) + } + return nil +} + +// The JSON marshalers are only here for API backward compatibility +// (programs that explicitly look for these two methods). JSON works +// fine with the TextMarshaler only. + +// MarshalJSON implements the json.Marshaler interface. +func (x *Int) MarshalJSON() ([]byte, error) { + return x.MarshalText() +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (z *Int) UnmarshalJSON(text []byte) error { + // Ignore null, like in the main JSON package. + if string(text) == "null" { + return nil + } + return z.UnmarshalText(text) +} diff --git a/contrib/go/_std_1.18/src/math/big/nat.go b/contrib/go/_std_1.18/src/math/big/nat.go new file mode 100644 index 0000000000..140c619c8c --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/nat.go @@ -0,0 +1,1244 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements unsigned multi-precision integers (natural +// numbers). They are the building blocks for the implementation +// of signed integers, rationals, and floating-point numbers. +// +// Caution: This implementation relies on the function "alias" +// which assumes that (nat) slice capacities are never +// changed (no 3-operand slice expressions). If that +// changes, alias needs to be updated for correctness. + +package big + +import ( + "encoding/binary" + "math/bits" + "math/rand" + "sync" +) + +// An unsigned integer x of the form +// +// x = x[n-1]*_B^(n-1) + x[n-2]*_B^(n-2) + ... + x[1]*_B + x[0] +// +// with 0 <= x[i] < _B and 0 <= i < n is stored in a slice of length n, +// with the digits x[i] as the slice elements. +// +// A number is normalized if the slice contains no leading 0 digits. +// During arithmetic operations, denormalized values may occur but are +// always normalized before returning the final result. The normalized +// representation of 0 is the empty or nil slice (length = 0). +// +type nat []Word + +var ( + natOne = nat{1} + natTwo = nat{2} + natFive = nat{5} + natTen = nat{10} +) + +func (z nat) clear() { + for i := range z { + z[i] = 0 + } +} + +func (z nat) norm() nat { + i := len(z) + for i > 0 && z[i-1] == 0 { + i-- + } + return z[0:i] +} + +func (z nat) make(n int) nat { + if n <= cap(z) { + return z[:n] // reuse z + } + if n == 1 { + // Most nats start small and stay that way; don't over-allocate. + return make(nat, 1) + } + // Choosing a good value for e has significant performance impact + // because it increases the chance that a value can be reused. + const e = 4 // extra capacity + return make(nat, n, n+e) +} + +func (z nat) setWord(x Word) nat { + if x == 0 { + return z[:0] + } + z = z.make(1) + z[0] = x + return z +} + +func (z nat) setUint64(x uint64) nat { + // single-word value + if w := Word(x); uint64(w) == x { + return z.setWord(w) + } + // 2-word value + z = z.make(2) + z[1] = Word(x >> 32) + z[0] = Word(x) + return z +} + +func (z nat) set(x nat) nat { + z = z.make(len(x)) + copy(z, x) + return z +} + +func (z nat) add(x, y nat) nat { + m := len(x) + n := len(y) + + switch { + case m < n: + return z.add(y, x) + case m == 0: + // n == 0 because m >= n; result is 0 + return z[:0] + case n == 0: + // result is x + return z.set(x) + } + // m > 0 + + z = z.make(m + 1) + c := addVV(z[0:n], x, y) + if m > n { + c = addVW(z[n:m], x[n:], c) + } + z[m] = c + + return z.norm() +} + +func (z nat) sub(x, y nat) nat { + m := len(x) + n := len(y) + + switch { + case m < n: + panic("underflow") + case m == 0: + // n == 0 because m >= n; result is 0 + return z[:0] + case n == 0: + // result is x + return z.set(x) + } + // m > 0 + + z = z.make(m) + c := subVV(z[0:n], x, y) + if m > n { + c = subVW(z[n:], x[n:], c) + } + if c != 0 { + panic("underflow") + } + + return z.norm() +} + +func (x nat) cmp(y nat) (r int) { + m := len(x) + n := len(y) + if m != n || m == 0 { + switch { + case m < n: + r = -1 + case m > n: + r = 1 + } + return + } + + i := m - 1 + for i > 0 && x[i] == y[i] { + i-- + } + + switch { + case x[i] < y[i]: + r = -1 + case x[i] > y[i]: + r = 1 + } + return +} + +func (z nat) mulAddWW(x nat, y, r Word) nat { + m := len(x) + if m == 0 || y == 0 { + return z.setWord(r) // result is r + } + // m > 0 + + z = z.make(m + 1) + z[m] = mulAddVWW(z[0:m], x, y, r) + + return z.norm() +} + +// basicMul multiplies x and y and leaves the result in z. +// The (non-normalized) result is placed in z[0 : len(x) + len(y)]. +func basicMul(z, x, y nat) { + z[0 : len(x)+len(y)].clear() // initialize z + for i, d := range y { + if d != 0 { + z[len(x)+i] = addMulVVW(z[i:i+len(x)], x, d) + } + } +} + +// montgomery computes z mod m = x*y*2**(-n*_W) mod m, +// assuming k = -1/m mod 2**_W. +// z is used for storing the result which is returned; +// z must not alias x, y or m. +// See Gueron, "Efficient Software Implementations of Modular Exponentiation". +// https://eprint.iacr.org/2011/239.pdf +// In the terminology of that paper, this is an "Almost Montgomery Multiplication": +// x and y are required to satisfy 0 <= z < 2**(n*_W) and then the result +// z is guaranteed to satisfy 0 <= z < 2**(n*_W), but it may not be < m. +func (z nat) montgomery(x, y, m nat, k Word, n int) nat { + // This code assumes x, y, m are all the same length, n. + // (required by addMulVVW and the for loop). + // It also assumes that x, y are already reduced mod m, + // or else the result will not be properly reduced. + if len(x) != n || len(y) != n || len(m) != n { + panic("math/big: mismatched montgomery number lengths") + } + z = z.make(n * 2) + z.clear() + var c Word + for i := 0; i < n; i++ { + d := y[i] + c2 := addMulVVW(z[i:n+i], x, d) + t := z[i] * k + c3 := addMulVVW(z[i:n+i], m, t) + cx := c + c2 + cy := cx + c3 + z[n+i] = cy + if cx < c2 || cy < c3 { + c = 1 + } else { + c = 0 + } + } + if c != 0 { + subVV(z[:n], z[n:], m) + } else { + copy(z[:n], z[n:]) + } + return z[:n] +} + +// Fast version of z[0:n+n>>1].add(z[0:n+n>>1], x[0:n]) w/o bounds checks. +// Factored out for readability - do not use outside karatsuba. +func karatsubaAdd(z, x nat, n int) { + if c := addVV(z[0:n], z, x); c != 0 { + addVW(z[n:n+n>>1], z[n:], c) + } +} + +// Like karatsubaAdd, but does subtract. +func karatsubaSub(z, x nat, n int) { + if c := subVV(z[0:n], z, x); c != 0 { + subVW(z[n:n+n>>1], z[n:], c) + } +} + +// Operands that are shorter than karatsubaThreshold are multiplied using +// "grade school" multiplication; for longer operands the Karatsuba algorithm +// is used. +var karatsubaThreshold = 40 // computed by calibrate_test.go + +// karatsuba multiplies x and y and leaves the result in z. +// Both x and y must have the same length n and n must be a +// power of 2. The result vector z must have len(z) >= 6*n. +// The (non-normalized) result is placed in z[0 : 2*n]. +func karatsuba(z, x, y nat) { + n := len(y) + + // Switch to basic multiplication if numbers are odd or small. + // (n is always even if karatsubaThreshold is even, but be + // conservative) + if n&1 != 0 || n < karatsubaThreshold || n < 2 { + basicMul(z, x, y) + return + } + // n&1 == 0 && n >= karatsubaThreshold && n >= 2 + + // Karatsuba multiplication is based on the observation that + // for two numbers x and y with: + // + // x = x1*b + x0 + // y = y1*b + y0 + // + // the product x*y can be obtained with 3 products z2, z1, z0 + // instead of 4: + // + // x*y = x1*y1*b*b + (x1*y0 + x0*y1)*b + x0*y0 + // = z2*b*b + z1*b + z0 + // + // with: + // + // xd = x1 - x0 + // yd = y0 - y1 + // + // z1 = xd*yd + z2 + z0 + // = (x1-x0)*(y0 - y1) + z2 + z0 + // = x1*y0 - x1*y1 - x0*y0 + x0*y1 + z2 + z0 + // = x1*y0 - z2 - z0 + x0*y1 + z2 + z0 + // = x1*y0 + x0*y1 + + // split x, y into "digits" + n2 := n >> 1 // n2 >= 1 + x1, x0 := x[n2:], x[0:n2] // x = x1*b + y0 + y1, y0 := y[n2:], y[0:n2] // y = y1*b + y0 + + // z is used for the result and temporary storage: + // + // 6*n 5*n 4*n 3*n 2*n 1*n 0*n + // z = [z2 copy|z0 copy| xd*yd | yd:xd | x1*y1 | x0*y0 ] + // + // For each recursive call of karatsuba, an unused slice of + // z is passed in that has (at least) half the length of the + // caller's z. + + // compute z0 and z2 with the result "in place" in z + karatsuba(z, x0, y0) // z0 = x0*y0 + karatsuba(z[n:], x1, y1) // z2 = x1*y1 + + // compute xd (or the negative value if underflow occurs) + s := 1 // sign of product xd*yd + xd := z[2*n : 2*n+n2] + if subVV(xd, x1, x0) != 0 { // x1-x0 + s = -s + subVV(xd, x0, x1) // x0-x1 + } + + // compute yd (or the negative value if underflow occurs) + yd := z[2*n+n2 : 3*n] + if subVV(yd, y0, y1) != 0 { // y0-y1 + s = -s + subVV(yd, y1, y0) // y1-y0 + } + + // p = (x1-x0)*(y0-y1) == x1*y0 - x1*y1 - x0*y0 + x0*y1 for s > 0 + // p = (x0-x1)*(y0-y1) == x0*y0 - x0*y1 - x1*y0 + x1*y1 for s < 0 + p := z[n*3:] + karatsuba(p, xd, yd) + + // save original z2:z0 + // (ok to use upper half of z since we're done recursing) + r := z[n*4:] + copy(r, z[:n*2]) + + // add up all partial products + // + // 2*n n 0 + // z = [ z2 | z0 ] + // + [ z0 ] + // + [ z2 ] + // + [ p ] + // + karatsubaAdd(z[n2:], r, n) + karatsubaAdd(z[n2:], r[n:], n) + if s > 0 { + karatsubaAdd(z[n2:], p, n) + } else { + karatsubaSub(z[n2:], p, n) + } +} + +// alias reports whether x and y share the same base array. +// Note: alias assumes that the capacity of underlying arrays +// is never changed for nat values; i.e. that there are +// no 3-operand slice expressions in this code (or worse, +// reflect-based operations to the same effect). +func alias(x, y nat) bool { + return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1] +} + +// addAt implements z += x<<(_W*i); z must be long enough. +// (we don't use nat.add because we need z to stay the same +// slice, and we don't need to normalize z after each addition) +func addAt(z, x nat, i int) { + if n := len(x); n > 0 { + if c := addVV(z[i:i+n], z[i:], x); c != 0 { + j := i + n + if j < len(z) { + addVW(z[j:], z[j:], c) + } + } + } +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} + +// karatsubaLen computes an approximation to the maximum k <= n such that +// k = p<<i for a number p <= threshold and an i >= 0. Thus, the +// result is the largest number that can be divided repeatedly by 2 before +// becoming about the value of threshold. +func karatsubaLen(n, threshold int) int { + i := uint(0) + for n > threshold { + n >>= 1 + i++ + } + return n << i +} + +func (z nat) mul(x, y nat) nat { + m := len(x) + n := len(y) + + switch { + case m < n: + return z.mul(y, x) + case m == 0 || n == 0: + return z[:0] + case n == 1: + return z.mulAddWW(x, y[0], 0) + } + // m >= n > 1 + + // determine if z can be reused + if alias(z, x) || alias(z, y) { + z = nil // z is an alias for x or y - cannot reuse + } + + // use basic multiplication if the numbers are small + if n < karatsubaThreshold { + z = z.make(m + n) + basicMul(z, x, y) + return z.norm() + } + // m >= n && n >= karatsubaThreshold && n >= 2 + + // determine Karatsuba length k such that + // + // x = xh*b + x0 (0 <= x0 < b) + // y = yh*b + y0 (0 <= y0 < b) + // b = 1<<(_W*k) ("base" of digits xi, yi) + // + k := karatsubaLen(n, karatsubaThreshold) + // k <= n + + // multiply x0 and y0 via Karatsuba + x0 := x[0:k] // x0 is not normalized + y0 := y[0:k] // y0 is not normalized + z = z.make(max(6*k, m+n)) // enough space for karatsuba of x0*y0 and full result of x*y + karatsuba(z, x0, y0) + z = z[0 : m+n] // z has final length but may be incomplete + z[2*k:].clear() // upper portion of z is garbage (and 2*k <= m+n since k <= n <= m) + + // If xh != 0 or yh != 0, add the missing terms to z. For + // + // xh = xi*b^i + ... + x2*b^2 + x1*b (0 <= xi < b) + // yh = y1*b (0 <= y1 < b) + // + // the missing terms are + // + // x0*y1*b and xi*y0*b^i, xi*y1*b^(i+1) for i > 0 + // + // since all the yi for i > 1 are 0 by choice of k: If any of them + // were > 0, then yh >= b^2 and thus y >= b^2. Then k' = k*2 would + // be a larger valid threshold contradicting the assumption about k. + // + if k < n || m != n { + tp := getNat(3 * k) + t := *tp + + // add x0*y1*b + x0 := x0.norm() + y1 := y[k:] // y1 is normalized because y is + t = t.mul(x0, y1) // update t so we don't lose t's underlying array + addAt(z, t, k) + + // add xi*y0<<i, xi*y1*b<<(i+k) + y0 := y0.norm() + for i := k; i < len(x); i += k { + xi := x[i:] + if len(xi) > k { + xi = xi[:k] + } + xi = xi.norm() + t = t.mul(xi, y0) + addAt(z, t, i) + t = t.mul(xi, y1) + addAt(z, t, i+k) + } + + putNat(tp) + } + + return z.norm() +} + +// basicSqr sets z = x*x and is asymptotically faster than basicMul +// by about a factor of 2, but slower for small arguments due to overhead. +// Requirements: len(x) > 0, len(z) == 2*len(x) +// The (non-normalized) result is placed in z. +func basicSqr(z, x nat) { + n := len(x) + tp := getNat(2 * n) + t := *tp // temporary variable to hold the products + t.clear() + z[1], z[0] = mulWW(x[0], x[0]) // the initial square + for i := 1; i < n; i++ { + d := x[i] + // z collects the squares x[i] * x[i] + z[2*i+1], z[2*i] = mulWW(d, d) + // t collects the products x[i] * x[j] where j < i + t[2*i] = addMulVVW(t[i:2*i], x[0:i], d) + } + t[2*n-1] = shlVU(t[1:2*n-1], t[1:2*n-1], 1) // double the j < i products + addVV(z, z, t) // combine the result + putNat(tp) +} + +// karatsubaSqr squares x and leaves the result in z. +// len(x) must be a power of 2 and len(z) >= 6*len(x). +// The (non-normalized) result is placed in z[0 : 2*len(x)]. +// +// The algorithm and the layout of z are the same as for karatsuba. +func karatsubaSqr(z, x nat) { + n := len(x) + + if n&1 != 0 || n < karatsubaSqrThreshold || n < 2 { + basicSqr(z[:2*n], x) + return + } + + n2 := n >> 1 + x1, x0 := x[n2:], x[0:n2] + + karatsubaSqr(z, x0) + karatsubaSqr(z[n:], x1) + + // s = sign(xd*yd) == -1 for xd != 0; s == 1 for xd == 0 + xd := z[2*n : 2*n+n2] + if subVV(xd, x1, x0) != 0 { + subVV(xd, x0, x1) + } + + p := z[n*3:] + karatsubaSqr(p, xd) + + r := z[n*4:] + copy(r, z[:n*2]) + + karatsubaAdd(z[n2:], r, n) + karatsubaAdd(z[n2:], r[n:], n) + karatsubaSub(z[n2:], p, n) // s == -1 for p != 0; s == 1 for p == 0 +} + +// Operands that are shorter than basicSqrThreshold are squared using +// "grade school" multiplication; for operands longer than karatsubaSqrThreshold +// we use the Karatsuba algorithm optimized for x == y. +var basicSqrThreshold = 20 // computed by calibrate_test.go +var karatsubaSqrThreshold = 260 // computed by calibrate_test.go + +// z = x*x +func (z nat) sqr(x nat) nat { + n := len(x) + switch { + case n == 0: + return z[:0] + case n == 1: + d := x[0] + z = z.make(2) + z[1], z[0] = mulWW(d, d) + return z.norm() + } + + if alias(z, x) { + z = nil // z is an alias for x - cannot reuse + } + + if n < basicSqrThreshold { + z = z.make(2 * n) + basicMul(z, x, x) + return z.norm() + } + if n < karatsubaSqrThreshold { + z = z.make(2 * n) + basicSqr(z, x) + return z.norm() + } + + // Use Karatsuba multiplication optimized for x == y. + // The algorithm and layout of z are the same as for mul. + + // z = (x1*b + x0)^2 = x1^2*b^2 + 2*x1*x0*b + x0^2 + + k := karatsubaLen(n, karatsubaSqrThreshold) + + x0 := x[0:k] + z = z.make(max(6*k, 2*n)) + karatsubaSqr(z, x0) // z = x0^2 + z = z[0 : 2*n] + z[2*k:].clear() + + if k < n { + tp := getNat(2 * k) + t := *tp + x0 := x0.norm() + x1 := x[k:] + t = t.mul(x0, x1) + addAt(z, t, k) + addAt(z, t, k) // z = 2*x1*x0*b + x0^2 + t = t.sqr(x1) + addAt(z, t, 2*k) // z = x1^2*b^2 + 2*x1*x0*b + x0^2 + putNat(tp) + } + + return z.norm() +} + +// mulRange computes the product of all the unsigned integers in the +// range [a, b] inclusively. If a > b (empty range), the result is 1. +func (z nat) mulRange(a, b uint64) nat { + switch { + case a == 0: + // cut long ranges short (optimization) + return z.setUint64(0) + case a > b: + return z.setUint64(1) + case a == b: + return z.setUint64(a) + case a+1 == b: + return z.mul(nat(nil).setUint64(a), nat(nil).setUint64(b)) + } + m := (a + b) / 2 + return z.mul(nat(nil).mulRange(a, m), nat(nil).mulRange(m+1, b)) +} + +// getNat returns a *nat of len n. The contents may not be zero. +// The pool holds *nat to avoid allocation when converting to interface{}. +func getNat(n int) *nat { + var z *nat + if v := natPool.Get(); v != nil { + z = v.(*nat) + } + if z == nil { + z = new(nat) + } + *z = z.make(n) + return z +} + +func putNat(x *nat) { + natPool.Put(x) +} + +var natPool sync.Pool + +// Length of x in bits. x must be normalized. +func (x nat) bitLen() int { + if i := len(x) - 1; i >= 0 { + return i*_W + bits.Len(uint(x[i])) + } + return 0 +} + +// trailingZeroBits returns the number of consecutive least significant zero +// bits of x. +func (x nat) trailingZeroBits() uint { + if len(x) == 0 { + return 0 + } + var i uint + for x[i] == 0 { + i++ + } + // x[i] != 0 + return i*_W + uint(bits.TrailingZeros(uint(x[i]))) +} + +func same(x, y nat) bool { + return len(x) == len(y) && len(x) > 0 && &x[0] == &y[0] +} + +// z = x << s +func (z nat) shl(x nat, s uint) nat { + if s == 0 { + if same(z, x) { + return z + } + if !alias(z, x) { + return z.set(x) + } + } + + m := len(x) + if m == 0 { + return z[:0] + } + // m > 0 + + n := m + int(s/_W) + z = z.make(n + 1) + z[n] = shlVU(z[n-m:n], x, s%_W) + z[0 : n-m].clear() + + return z.norm() +} + +// z = x >> s +func (z nat) shr(x nat, s uint) nat { + if s == 0 { + if same(z, x) { + return z + } + if !alias(z, x) { + return z.set(x) + } + } + + m := len(x) + n := m - int(s/_W) + if n <= 0 { + return z[:0] + } + // n > 0 + + z = z.make(n) + shrVU(z, x[m-n:], s%_W) + + return z.norm() +} + +func (z nat) setBit(x nat, i uint, b uint) nat { + j := int(i / _W) + m := Word(1) << (i % _W) + n := len(x) + switch b { + case 0: + z = z.make(n) + copy(z, x) + if j >= n { + // no need to grow + return z + } + z[j] &^= m + return z.norm() + case 1: + if j >= n { + z = z.make(j + 1) + z[n:].clear() + } else { + z = z.make(n) + } + copy(z, x) + z[j] |= m + // no need to normalize + return z + } + panic("set bit is not 0 or 1") +} + +// bit returns the value of the i'th bit, with lsb == bit 0. +func (x nat) bit(i uint) uint { + j := i / _W + if j >= uint(len(x)) { + return 0 + } + // 0 <= j < len(x) + return uint(x[j] >> (i % _W) & 1) +} + +// sticky returns 1 if there's a 1 bit within the +// i least significant bits, otherwise it returns 0. +func (x nat) sticky(i uint) uint { + j := i / _W + if j >= uint(len(x)) { + if len(x) == 0 { + return 0 + } + return 1 + } + // 0 <= j < len(x) + for _, x := range x[:j] { + if x != 0 { + return 1 + } + } + if x[j]<<(_W-i%_W) != 0 { + return 1 + } + return 0 +} + +func (z nat) and(x, y nat) nat { + m := len(x) + n := len(y) + if m > n { + m = n + } + // m <= n + + z = z.make(m) + for i := 0; i < m; i++ { + z[i] = x[i] & y[i] + } + + return z.norm() +} + +func (z nat) andNot(x, y nat) nat { + m := len(x) + n := len(y) + if n > m { + n = m + } + // m >= n + + z = z.make(m) + for i := 0; i < n; i++ { + z[i] = x[i] &^ y[i] + } + copy(z[n:m], x[n:m]) + + return z.norm() +} + +func (z nat) or(x, y nat) nat { + m := len(x) + n := len(y) + s := x + if m < n { + n, m = m, n + s = y + } + // m >= n + + z = z.make(m) + for i := 0; i < n; i++ { + z[i] = x[i] | y[i] + } + copy(z[n:m], s[n:m]) + + return z.norm() +} + +func (z nat) xor(x, y nat) nat { + m := len(x) + n := len(y) + s := x + if m < n { + n, m = m, n + s = y + } + // m >= n + + z = z.make(m) + for i := 0; i < n; i++ { + z[i] = x[i] ^ y[i] + } + copy(z[n:m], s[n:m]) + + return z.norm() +} + +// random creates a random integer in [0..limit), using the space in z if +// possible. n is the bit length of limit. +func (z nat) random(rand *rand.Rand, limit nat, n int) nat { + if alias(z, limit) { + z = nil // z is an alias for limit - cannot reuse + } + z = z.make(len(limit)) + + bitLengthOfMSW := uint(n % _W) + if bitLengthOfMSW == 0 { + bitLengthOfMSW = _W + } + mask := Word((1 << bitLengthOfMSW) - 1) + + for { + switch _W { + case 32: + for i := range z { + z[i] = Word(rand.Uint32()) + } + case 64: + for i := range z { + z[i] = Word(rand.Uint32()) | Word(rand.Uint32())<<32 + } + default: + panic("unknown word size") + } + z[len(limit)-1] &= mask + if z.cmp(limit) < 0 { + break + } + } + + return z.norm() +} + +// If m != 0 (i.e., len(m) != 0), expNN sets z to x**y mod m; +// otherwise it sets z to x**y. The result is the value of z. +func (z nat) expNN(x, y, m nat) nat { + if alias(z, x) || alias(z, y) { + // We cannot allow in-place modification of x or y. + z = nil + } + + // x**y mod 1 == 0 + if len(m) == 1 && m[0] == 1 { + return z.setWord(0) + } + // m == 0 || m > 1 + + // x**0 == 1 + if len(y) == 0 { + return z.setWord(1) + } + // y > 0 + + // x**1 mod m == x mod m + if len(y) == 1 && y[0] == 1 && len(m) != 0 { + _, z = nat(nil).div(z, x, m) + return z + } + // y > 1 + + if len(m) != 0 { + // We likely end up being as long as the modulus. + z = z.make(len(m)) + } + z = z.set(x) + + // If the base is non-trivial and the exponent is large, we use + // 4-bit, windowed exponentiation. This involves precomputing 14 values + // (x^2...x^15) but then reduces the number of multiply-reduces by a + // third. Even for a 32-bit exponent, this reduces the number of + // operations. Uses Montgomery method for odd moduli. + if x.cmp(natOne) > 0 && len(y) > 1 && len(m) > 0 { + if m[0]&1 == 1 { + return z.expNNMontgomery(x, y, m) + } + return z.expNNWindowed(x, y, m) + } + + v := y[len(y)-1] // v > 0 because y is normalized and y > 0 + shift := nlz(v) + 1 + v <<= shift + var q nat + + const mask = 1 << (_W - 1) + + // We walk through the bits of the exponent one by one. Each time we + // see a bit, we square, thus doubling the power. If the bit is a one, + // we also multiply by x, thus adding one to the power. + + w := _W - int(shift) + // zz and r are used to avoid allocating in mul and div as + // otherwise the arguments would alias. + var zz, r nat + for j := 0; j < w; j++ { + zz = zz.sqr(z) + zz, z = z, zz + + if v&mask != 0 { + zz = zz.mul(z, x) + zz, z = z, zz + } + + if len(m) != 0 { + zz, r = zz.div(r, z, m) + zz, r, q, z = q, z, zz, r + } + + v <<= 1 + } + + for i := len(y) - 2; i >= 0; i-- { + v = y[i] + + for j := 0; j < _W; j++ { + zz = zz.sqr(z) + zz, z = z, zz + + if v&mask != 0 { + zz = zz.mul(z, x) + zz, z = z, zz + } + + if len(m) != 0 { + zz, r = zz.div(r, z, m) + zz, r, q, z = q, z, zz, r + } + + v <<= 1 + } + } + + return z.norm() +} + +// expNNWindowed calculates x**y mod m using a fixed, 4-bit window. +func (z nat) expNNWindowed(x, y, m nat) nat { + // zz and r are used to avoid allocating in mul and div as otherwise + // the arguments would alias. + var zz, r nat + + const n = 4 + // powers[i] contains x^i. + var powers [1 << n]nat + powers[0] = natOne + powers[1] = x + for i := 2; i < 1<<n; i += 2 { + p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1] + *p = p.sqr(*p2) + zz, r = zz.div(r, *p, m) + *p, r = r, *p + *p1 = p1.mul(*p, x) + zz, r = zz.div(r, *p1, m) + *p1, r = r, *p1 + } + + z = z.setWord(1) + + for i := len(y) - 1; i >= 0; i-- { + yi := y[i] + for j := 0; j < _W; j += n { + if i != len(y)-1 || j != 0 { + // Unrolled loop for significant performance + // gain. Use go test -bench=".*" in crypto/rsa + // to check performance before making changes. + zz = zz.sqr(z) + zz, z = z, zz + zz, r = zz.div(r, z, m) + z, r = r, z + + zz = zz.sqr(z) + zz, z = z, zz + zz, r = zz.div(r, z, m) + z, r = r, z + + zz = zz.sqr(z) + zz, z = z, zz + zz, r = zz.div(r, z, m) + z, r = r, z + + zz = zz.sqr(z) + zz, z = z, zz + zz, r = zz.div(r, z, m) + z, r = r, z + } + + zz = zz.mul(z, powers[yi>>(_W-n)]) + zz, z = z, zz + zz, r = zz.div(r, z, m) + z, r = r, z + + yi <<= n + } + } + + return z.norm() +} + +// expNNMontgomery calculates x**y mod m using a fixed, 4-bit window. +// Uses Montgomery representation. +func (z nat) expNNMontgomery(x, y, m nat) nat { + numWords := len(m) + + // We want the lengths of x and m to be equal. + // It is OK if x >= m as long as len(x) == len(m). + if len(x) > numWords { + _, x = nat(nil).div(nil, x, m) + // Note: now len(x) <= numWords, not guaranteed ==. + } + if len(x) < numWords { + rr := make(nat, numWords) + copy(rr, x) + x = rr + } + + // Ideally the precomputations would be performed outside, and reused + // k0 = -m**-1 mod 2**_W. Algorithm from: Dumas, J.G. "On Newton–Raphson + // Iteration for Multiplicative Inverses Modulo Prime Powers". + k0 := 2 - m[0] + t := m[0] - 1 + for i := 1; i < _W; i <<= 1 { + t *= t + k0 *= (t + 1) + } + k0 = -k0 + + // RR = 2**(2*_W*len(m)) mod m + RR := nat(nil).setWord(1) + zz := nat(nil).shl(RR, uint(2*numWords*_W)) + _, RR = nat(nil).div(RR, zz, m) + if len(RR) < numWords { + zz = zz.make(numWords) + copy(zz, RR) + RR = zz + } + // one = 1, with equal length to that of m + one := make(nat, numWords) + one[0] = 1 + + const n = 4 + // powers[i] contains x^i + var powers [1 << n]nat + powers[0] = powers[0].montgomery(one, RR, m, k0, numWords) + powers[1] = powers[1].montgomery(x, RR, m, k0, numWords) + for i := 2; i < 1<<n; i++ { + powers[i] = powers[i].montgomery(powers[i-1], powers[1], m, k0, numWords) + } + + // initialize z = 1 (Montgomery 1) + z = z.make(numWords) + copy(z, powers[0]) + + zz = zz.make(numWords) + + // same windowed exponent, but with Montgomery multiplications + for i := len(y) - 1; i >= 0; i-- { + yi := y[i] + for j := 0; j < _W; j += n { + if i != len(y)-1 || j != 0 { + zz = zz.montgomery(z, z, m, k0, numWords) + z = z.montgomery(zz, zz, m, k0, numWords) + zz = zz.montgomery(z, z, m, k0, numWords) + z = z.montgomery(zz, zz, m, k0, numWords) + } + zz = zz.montgomery(z, powers[yi>>(_W-n)], m, k0, numWords) + z, zz = zz, z + yi <<= n + } + } + // convert to regular number + zz = zz.montgomery(z, one, m, k0, numWords) + + // One last reduction, just in case. + // See golang.org/issue/13907. + if zz.cmp(m) >= 0 { + // Common case is m has high bit set; in that case, + // since zz is the same length as m, there can be just + // one multiple of m to remove. Just subtract. + // We think that the subtract should be sufficient in general, + // so do that unconditionally, but double-check, + // in case our beliefs are wrong. + // The div is not expected to be reached. + zz = zz.sub(zz, m) + if zz.cmp(m) >= 0 { + _, zz = nat(nil).div(nil, zz, m) + } + } + + return zz.norm() +} + +// bytes writes the value of z into buf using big-endian encoding. +// The value of z is encoded in the slice buf[i:]. If the value of z +// cannot be represented in buf, bytes panics. The number i of unused +// bytes at the beginning of buf is returned as result. +func (z nat) bytes(buf []byte) (i int) { + i = len(buf) + for _, d := range z { + for j := 0; j < _S; j++ { + i-- + if i >= 0 { + buf[i] = byte(d) + } else if byte(d) != 0 { + panic("math/big: buffer too small to fit value") + } + d >>= 8 + } + } + + if i < 0 { + i = 0 + } + for i < len(buf) && buf[i] == 0 { + i++ + } + + return +} + +// bigEndianWord returns the contents of buf interpreted as a big-endian encoded Word value. +func bigEndianWord(buf []byte) Word { + if _W == 64 { + return Word(binary.BigEndian.Uint64(buf)) + } + return Word(binary.BigEndian.Uint32(buf)) +} + +// setBytes interprets buf as the bytes of a big-endian unsigned +// integer, sets z to that value, and returns z. +func (z nat) setBytes(buf []byte) nat { + z = z.make((len(buf) + _S - 1) / _S) + + i := len(buf) + for k := 0; i >= _S; k++ { + z[k] = bigEndianWord(buf[i-_S : i]) + i -= _S + } + if i > 0 { + var d Word + for s := uint(0); i > 0; s += 8 { + d |= Word(buf[i-1]) << s + i-- + } + z[len(z)-1] = d + } + + return z.norm() +} + +// sqrt sets z = ⌊√x⌋ +func (z nat) sqrt(x nat) nat { + if x.cmp(natOne) <= 0 { + return z.set(x) + } + if alias(z, x) { + z = nil + } + + // Start with value known to be too large and repeat "z = ⌊(z + ⌊x/z⌋)/2⌋" until it stops getting smaller. + // See Brent and Zimmermann, Modern Computer Arithmetic, Algorithm 1.13 (SqrtInt). + // https://members.loria.fr/PZimmermann/mca/pub226.html + // If x is one less than a perfect square, the sequence oscillates between the correct z and z+1; + // otherwise it converges to the correct z and stays there. + var z1, z2 nat + z1 = z + z1 = z1.setUint64(1) + z1 = z1.shl(z1, uint(x.bitLen()+1)/2) // must be ≥ √x + for n := 0; ; n++ { + z2, _ = z2.div(nil, x, z1) + z2 = z2.add(z2, z1) + z2 = z2.shr(z2, 1) + if z2.cmp(z1) >= 0 { + // z1 is answer. + // Figure out whether z1 or z2 is currently aliased to z by looking at loop count. + if n&1 == 0 { + return z1 + } + return z.set(z1) + } + z1, z2 = z2, z1 + } +} diff --git a/contrib/go/_std_1.18/src/math/big/natconv.go b/contrib/go/_std_1.18/src/math/big/natconv.go new file mode 100644 index 0000000000..42d1cccf6f --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/natconv.go @@ -0,0 +1,512 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements nat-to-string conversion functions. + +package big + +import ( + "errors" + "fmt" + "io" + "math" + "math/bits" + "sync" +) + +const digits = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +// Note: MaxBase = len(digits), but it must remain an untyped rune constant +// for API compatibility. + +// MaxBase is the largest number base accepted for string conversions. +const MaxBase = 10 + ('z' - 'a' + 1) + ('Z' - 'A' + 1) +const maxBaseSmall = 10 + ('z' - 'a' + 1) + +// maxPow returns (b**n, n) such that b**n is the largest power b**n <= _M. +// For instance maxPow(10) == (1e19, 19) for 19 decimal digits in a 64bit Word. +// In other words, at most n digits in base b fit into a Word. +// TODO(gri) replace this with a table, generated at build time. +func maxPow(b Word) (p Word, n int) { + p, n = b, 1 // assuming b <= _M + for max := _M / b; p <= max; { + // p == b**n && p <= max + p *= b + n++ + } + // p == b**n && p <= _M + return +} + +// pow returns x**n for n > 0, and 1 otherwise. +func pow(x Word, n int) (p Word) { + // n == sum of bi * 2**i, for 0 <= i < imax, and bi is 0 or 1 + // thus x**n == product of x**(2**i) for all i where bi == 1 + // (Russian Peasant Method for exponentiation) + p = 1 + for n > 0 { + if n&1 != 0 { + p *= x + } + x *= x + n >>= 1 + } + return +} + +// scan errors +var ( + errNoDigits = errors.New("number has no digits") + errInvalSep = errors.New("'_' must separate successive digits") +) + +// scan scans the number corresponding to the longest possible prefix +// from r representing an unsigned number in a given conversion base. +// scan returns the corresponding natural number res, the actual base b, +// a digit count, and a read or syntax error err, if any. +// +// For base 0, an underscore character ``_'' may appear between a base +// prefix and an adjacent digit, and between successive digits; such +// underscores do not change the value of the number, or the returned +// digit count. Incorrect placement of underscores is reported as an +// error if there are no other errors. If base != 0, underscores are +// not recognized and thus terminate scanning like any other character +// that is not a valid radix point or digit. +// +// number = mantissa | prefix pmantissa . +// prefix = "0" [ "b" | "B" | "o" | "O" | "x" | "X" ] . +// mantissa = digits "." [ digits ] | digits | "." digits . +// pmantissa = [ "_" ] digits "." [ digits ] | [ "_" ] digits | "." digits . +// digits = digit { [ "_" ] digit } . +// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" . +// +// Unless fracOk is set, the base argument must be 0 or a value between +// 2 and MaxBase. If fracOk is set, the base argument must be one of +// 0, 2, 8, 10, or 16. Providing an invalid base argument leads to a run- +// time panic. +// +// For base 0, the number prefix determines the actual base: A prefix of +// ``0b'' or ``0B'' selects base 2, ``0o'' or ``0O'' selects base 8, and +// ``0x'' or ``0X'' selects base 16. If fracOk is false, a ``0'' prefix +// (immediately followed by digits) selects base 8 as well. Otherwise, +// the selected base is 10 and no prefix is accepted. +// +// If fracOk is set, a period followed by a fractional part is permitted. +// The result value is computed as if there were no period present; and +// the count value is used to determine the fractional part. +// +// For bases <= 36, lower and upper case letters are considered the same: +// The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35. +// For bases > 36, the upper case letters 'A' to 'Z' represent the digit +// values 36 to 61. +// +// A result digit count > 0 corresponds to the number of (non-prefix) digits +// parsed. A digit count <= 0 indicates the presence of a period (if fracOk +// is set, only), and -count is the number of fractional digits found. +// In this case, the actual value of the scanned number is res * b**count. +// +func (z nat) scan(r io.ByteScanner, base int, fracOk bool) (res nat, b, count int, err error) { + // reject invalid bases + baseOk := base == 0 || + !fracOk && 2 <= base && base <= MaxBase || + fracOk && (base == 2 || base == 8 || base == 10 || base == 16) + if !baseOk { + panic(fmt.Sprintf("invalid number base %d", base)) + } + + // prev encodes the previously seen char: it is one + // of '_', '0' (a digit), or '.' (anything else). A + // valid separator '_' may only occur after a digit + // and if base == 0. + prev := '.' + invalSep := false + + // one char look-ahead + ch, err := r.ReadByte() + + // determine actual base + b, prefix := base, 0 + if base == 0 { + // actual base is 10 unless there's a base prefix + b = 10 + if err == nil && ch == '0' { + prev = '0' + count = 1 + ch, err = r.ReadByte() + if err == nil { + // possibly one of 0b, 0B, 0o, 0O, 0x, 0X + switch ch { + case 'b', 'B': + b, prefix = 2, 'b' + case 'o', 'O': + b, prefix = 8, 'o' + case 'x', 'X': + b, prefix = 16, 'x' + default: + if !fracOk { + b, prefix = 8, '0' + } + } + if prefix != 0 { + count = 0 // prefix is not counted + if prefix != '0' { + ch, err = r.ReadByte() + } + } + } + } + } + + // convert string + // Algorithm: Collect digits in groups of at most n digits in di + // and then use mulAddWW for every such group to add them to the + // result. + z = z[:0] + b1 := Word(b) + bn, n := maxPow(b1) // at most n digits in base b1 fit into Word + di := Word(0) // 0 <= di < b1**i < bn + i := 0 // 0 <= i < n + dp := -1 // position of decimal point + for err == nil { + if ch == '.' && fracOk { + fracOk = false + if prev == '_' { + invalSep = true + } + prev = '.' + dp = count + } else if ch == '_' && base == 0 { + if prev != '0' { + invalSep = true + } + prev = '_' + } else { + // convert rune into digit value d1 + var d1 Word + switch { + case '0' <= ch && ch <= '9': + d1 = Word(ch - '0') + case 'a' <= ch && ch <= 'z': + d1 = Word(ch - 'a' + 10) + case 'A' <= ch && ch <= 'Z': + if b <= maxBaseSmall { + d1 = Word(ch - 'A' + 10) + } else { + d1 = Word(ch - 'A' + maxBaseSmall) + } + default: + d1 = MaxBase + 1 + } + if d1 >= b1 { + r.UnreadByte() // ch does not belong to number anymore + break + } + prev = '0' + count++ + + // collect d1 in di + di = di*b1 + d1 + i++ + + // if di is "full", add it to the result + if i == n { + z = z.mulAddWW(z, bn, di) + di = 0 + i = 0 + } + } + + ch, err = r.ReadByte() + } + + if err == io.EOF { + err = nil + } + + // other errors take precedence over invalid separators + if err == nil && (invalSep || prev == '_') { + err = errInvalSep + } + + if count == 0 { + // no digits found + if prefix == '0' { + // there was only the octal prefix 0 (possibly followed by separators and digits > 7); + // interpret as decimal 0 + return z[:0], 10, 1, err + } + err = errNoDigits // fall through; result will be 0 + } + + // add remaining digits to result + if i > 0 { + z = z.mulAddWW(z, pow(b1, i), di) + } + res = z.norm() + + // adjust count for fraction, if any + if dp >= 0 { + // 0 <= dp <= count + count = dp - count + } + + return +} + +// utoa converts x to an ASCII representation in the given base; +// base must be between 2 and MaxBase, inclusive. +func (x nat) utoa(base int) []byte { + return x.itoa(false, base) +} + +// itoa is like utoa but it prepends a '-' if neg && x != 0. +func (x nat) itoa(neg bool, base int) []byte { + if base < 2 || base > MaxBase { + panic("invalid base") + } + + // x == 0 + if len(x) == 0 { + return []byte("0") + } + // len(x) > 0 + + // allocate buffer for conversion + i := int(float64(x.bitLen())/math.Log2(float64(base))) + 1 // off by 1 at most + if neg { + i++ + } + s := make([]byte, i) + + // convert power of two and non power of two bases separately + if b := Word(base); b == b&-b { + // shift is base b digit size in bits + shift := uint(bits.TrailingZeros(uint(b))) // shift > 0 because b >= 2 + mask := Word(1<<shift - 1) + w := x[0] // current word + nbits := uint(_W) // number of unprocessed bits in w + + // convert less-significant words (include leading zeros) + for k := 1; k < len(x); k++ { + // convert full digits + for nbits >= shift { + i-- + s[i] = digits[w&mask] + w >>= shift + nbits -= shift + } + + // convert any partial leading digit and advance to next word + if nbits == 0 { + // no partial digit remaining, just advance + w = x[k] + nbits = _W + } else { + // partial digit in current word w (== x[k-1]) and next word x[k] + w |= x[k] << nbits + i-- + s[i] = digits[w&mask] + + // advance + w = x[k] >> (shift - nbits) + nbits = _W - (shift - nbits) + } + } + + // convert digits of most-significant word w (omit leading zeros) + for w != 0 { + i-- + s[i] = digits[w&mask] + w >>= shift + } + + } else { + bb, ndigits := maxPow(b) + + // construct table of successive squares of bb*leafSize to use in subdivisions + // result (table != nil) <=> (len(x) > leafSize > 0) + table := divisors(len(x), b, ndigits, bb) + + // preserve x, create local copy for use by convertWords + q := nat(nil).set(x) + + // convert q to string s in base b + q.convertWords(s, b, ndigits, bb, table) + + // strip leading zeros + // (x != 0; thus s must contain at least one non-zero digit + // and the loop will terminate) + i = 0 + for s[i] == '0' { + i++ + } + } + + if neg { + i-- + s[i] = '-' + } + + return s[i:] +} + +// Convert words of q to base b digits in s. If q is large, it is recursively "split in half" +// by nat/nat division using tabulated divisors. Otherwise, it is converted iteratively using +// repeated nat/Word division. +// +// The iterative method processes n Words by n divW() calls, each of which visits every Word in the +// incrementally shortened q for a total of n + (n-1) + (n-2) ... + 2 + 1, or n(n+1)/2 divW()'s. +// Recursive conversion divides q by its approximate square root, yielding two parts, each half +// the size of q. Using the iterative method on both halves means 2 * (n/2)(n/2 + 1)/2 divW()'s +// plus the expensive long div(). Asymptotically, the ratio is favorable at 1/2 the divW()'s, and +// is made better by splitting the subblocks recursively. Best is to split blocks until one more +// split would take longer (because of the nat/nat div()) than the twice as many divW()'s of the +// iterative approach. This threshold is represented by leafSize. Benchmarking of leafSize in the +// range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and +// ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for +// specific hardware. +// +func (q nat) convertWords(s []byte, b Word, ndigits int, bb Word, table []divisor) { + // split larger blocks recursively + if table != nil { + // len(q) > leafSize > 0 + var r nat + index := len(table) - 1 + for len(q) > leafSize { + // find divisor close to sqrt(q) if possible, but in any case < q + maxLength := q.bitLen() // ~= log2 q, or at of least largest possible q of this bit length + minLength := maxLength >> 1 // ~= log2 sqrt(q) + for index > 0 && table[index-1].nbits > minLength { + index-- // desired + } + if table[index].nbits >= maxLength && table[index].bbb.cmp(q) >= 0 { + index-- + if index < 0 { + panic("internal inconsistency") + } + } + + // split q into the two digit number (q'*bbb + r) to form independent subblocks + q, r = q.div(r, q, table[index].bbb) + + // convert subblocks and collect results in s[:h] and s[h:] + h := len(s) - table[index].ndigits + r.convertWords(s[h:], b, ndigits, bb, table[0:index]) + s = s[:h] // == q.convertWords(s, b, ndigits, bb, table[0:index+1]) + } + } + + // having split any large blocks now process the remaining (small) block iteratively + i := len(s) + var r Word + if b == 10 { + // hard-coding for 10 here speeds this up by 1.25x (allows for / and % by constants) + for len(q) > 0 { + // extract least significant, base bb "digit" + q, r = q.divW(q, bb) + for j := 0; j < ndigits && i > 0; j++ { + i-- + // avoid % computation since r%10 == r - int(r/10)*10; + // this appears to be faster for BenchmarkString10000Base10 + // and smaller strings (but a bit slower for larger ones) + t := r / 10 + s[i] = '0' + byte(r-t*10) + r = t + } + } + } else { + for len(q) > 0 { + // extract least significant, base bb "digit" + q, r = q.divW(q, bb) + for j := 0; j < ndigits && i > 0; j++ { + i-- + s[i] = digits[r%b] + r /= b + } + } + } + + // prepend high-order zeros + for i > 0 { // while need more leading zeros + i-- + s[i] = '0' + } +} + +// Split blocks greater than leafSize Words (or set to 0 to disable recursive conversion) +// Benchmark and configure leafSize using: go test -bench="Leaf" +// 8 and 16 effective on 3.0 GHz Xeon "Clovertown" CPU (128 byte cache lines) +// 8 and 16 effective on 2.66 GHz Core 2 Duo "Penryn" CPU +var leafSize int = 8 // number of Word-size binary values treat as a monolithic block + +type divisor struct { + bbb nat // divisor + nbits int // bit length of divisor (discounting leading zeros) ~= log2(bbb) + ndigits int // digit length of divisor in terms of output base digits +} + +var cacheBase10 struct { + sync.Mutex + table [64]divisor // cached divisors for base 10 +} + +// expWW computes x**y +func (z nat) expWW(x, y Word) nat { + return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil) +} + +// construct table of powers of bb*leafSize to use in subdivisions +func divisors(m int, b Word, ndigits int, bb Word) []divisor { + // only compute table when recursive conversion is enabled and x is large + if leafSize == 0 || m <= leafSize { + return nil + } + + // determine k where (bb**leafSize)**(2**k) >= sqrt(x) + k := 1 + for words := leafSize; words < m>>1 && k < len(cacheBase10.table); words <<= 1 { + k++ + } + + // reuse and extend existing table of divisors or create new table as appropriate + var table []divisor // for b == 10, table overlaps with cacheBase10.table + if b == 10 { + cacheBase10.Lock() + table = cacheBase10.table[0:k] // reuse old table for this conversion + } else { + table = make([]divisor, k) // create new table for this conversion + } + + // extend table + if table[k-1].ndigits == 0 { + // add new entries as needed + var larger nat + for i := 0; i < k; i++ { + if table[i].ndigits == 0 { + if i == 0 { + table[0].bbb = nat(nil).expWW(bb, Word(leafSize)) + table[0].ndigits = ndigits * leafSize + } else { + table[i].bbb = nat(nil).sqr(table[i-1].bbb) + table[i].ndigits = 2 * table[i-1].ndigits + } + + // optimization: exploit aggregated extra bits in macro blocks + larger = nat(nil).set(table[i].bbb) + for mulAddVWW(larger, larger, b, 0) == 0 { + table[i].bbb = table[i].bbb.set(larger) + table[i].ndigits++ + } + + table[i].nbits = table[i].bbb.bitLen() + } + } + } + + if b == 10 { + cacheBase10.Unlock() + } + + return table +} diff --git a/contrib/go/_std_1.18/src/math/big/natdiv.go b/contrib/go/_std_1.18/src/math/big/natdiv.go new file mode 100644 index 0000000000..882bb6d3ba --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/natdiv.go @@ -0,0 +1,884 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + +Multi-precision division. Here be dragons. + +Given u and v, where u is n+m digits, and v is n digits (with no leading zeros), +the goal is to return quo, rem such that u = quo*v + rem, where 0 ≤ rem < v. +That is, quo = ⌊u/v⌋ where ⌊x⌋ denotes the floor (truncation to integer) of x, +and rem = u - quo·v. + + +Long Division + +Division in a computer proceeds the same as long division in elementary school, +but computers are not as good as schoolchildren at following vague directions, +so we have to be much more precise about the actual steps and what can happen. + +We work from most to least significant digit of the quotient, doing: + + • Guess a digit q, the number of v to subtract from the current + section of u to zero out the topmost digit. + • Check the guess by multiplying q·v and comparing it against + the current section of u, adjusting the guess as needed. + • Subtract q·v from the current section of u. + • Add q to the corresponding section of the result quo. + +When all digits have been processed, the final remainder is left in u +and returned as rem. + +For example, here is a sketch of dividing 5 digits by 3 digits (n=3, m=2). + + q₂ q₁ q₀ + _________________ + v₂ v₁ v₀ ) u₄ u₃ u₂ u₁ u₀ + ↓ ↓ ↓ | | + [u₄ u₃ u₂]| | + - [ q₂·v ]| | + ----------- ↓ | + [ rem | u₁]| + - [ q₁·v ]| + ----------- ↓ + [ rem | u₀] + - [ q₀·v ] + ------------ + [ rem ] + +Instead of creating new storage for the remainders and copying digits from u +as indicated by the arrows, we use u's storage directly as both the source +and destination of the subtractions, so that the remainders overwrite +successive overlapping sections of u as the division proceeds, using a slice +of u to identify the current section. This avoids all the copying as well as +shifting of remainders. + +Division of u with n+m digits by v with n digits (in base B) can in general +produce at most m+1 digits, because: + + • u < B^(n+m) [B^(n+m) has n+m+1 digits] + • v ≥ B^(n-1) [B^(n-1) is the smallest n-digit number] + • u/v < B^(n+m) / B^(n-1) [divide bounds for u, v] + • u/v < B^(m+1) [simplify] + +The first step is special: it takes the top n digits of u and divides them by +the n digits of v, producing the first quotient digit and an n-digit remainder. +In the example, q₂ = ⌊u₄u₃u₂ / v⌋. + +The first step divides n digits by n digits to ensure that it produces only a +single digit. + +Each subsequent step appends the next digit from u to the remainder and divides +those n+1 digits by the n digits of v, producing another quotient digit and a +new n-digit remainder. + +Subsequent steps divide n+1 digits by n digits, an operation that in general +might produce two digits. However, as used in the algorithm, that division is +guaranteed to produce only a single digit. The dividend is of the form +rem·B + d, where rem is a remainder from the previous step and d is a single +digit, so: + + • rem ≤ v - 1 [rem is a remainder from dividing by v] + • rem·B ≤ v·B - B [multiply by B] + • d ≤ B - 1 [d is a single digit] + • rem·B + d ≤ v·B - 1 [add] + • rem·B + d < v·B [change ≤ to <] + • (rem·B + d)/v < B [divide by v] + + +Guess and Check + +At each step we need to divide n+1 digits by n digits, but this is for the +implementation of division by n digits, so we can't just invoke a division +routine: we _are_ the division routine. Instead, we guess at the answer and +then check it using multiplication. If the guess is wrong, we correct it. + +How can this guessing possibly be efficient? It turns out that the following +statement (let's call it the Good Guess Guarantee) is true. + +If + + • q = ⌊u/v⌋ where u is n+1 digits and v is n digits, + • q < B, and + • the topmost digit of v = vₙ₋₁ ≥ B/2, + +then q̂ = ⌊uₙuₙ₋₁ / vₙ₋₁⌋ satisfies q ≤ q̂ ≤ q+2. (Proof below.) + +That is, if we know the answer has only a single digit and we guess an answer +by ignoring the bottom n-1 digits of u and v, using a 2-by-1-digit division, +then that guess is at least as large as the correct answer. It is also not +too much larger: it is off by at most two from the correct answer. + +Note that in the first step of the overall division, which is an n-by-n-digit +division, the 2-by-1 guess uses an implicit uₙ = 0. + +Note that using a 2-by-1-digit division here does not mean calling ourselves +recursively. Instead, we use an efficient direct hardware implementation of +that operation. + +Note that because q is u/v rounded down, q·v must not exceed u: u ≥ q·v. +If a guess q̂ is too big, it will not satisfy this test. Viewed a different way, +the remainder r̂ for a given q̂ is u - q̂·v, which must be positive. If it is +negative, then the guess q̂ is too big. + +This gives us a way to compute q. First compute q̂ with 2-by-1-digit division. +Then, while u < q̂·v, decrement q̂; this loop executes at most twice, because +q̂ ≤ q+2. + + +Scaling Inputs + +The Good Guess Guarantee requires that the top digit of v (vₙ₋₁) be at least B/2. +For example in base 10, ⌊172/19⌋ = 9, but ⌊18/1⌋ = 18: the guess is wildly off +because the first digit 1 is smaller than B/2 = 5. + +We can ensure that v has a large top digit by multiplying both u and v by the +right amount. Continuing the example, if we multiply both 172 and 19 by 3, we +now have ⌊516/57⌋, the leading digit of v is now ≥ 5, and sure enough +⌊51/5⌋ = 10 is much closer to the correct answer 9. It would be easier here +to multiply by 4, because that can be done with a shift. Specifically, we can +always count the number of leading zeros i in the first digit of v and then +shift both u and v left by i bits. + +Having scaled u and v, the value ⌊u/v⌋ is unchanged, but the remainder will +be scaled: 172 mod 19 is 1, but 516 mod 57 is 3. We have to divide the remainder +by the scaling factor (shifting right i bits) when we finish. + +Note that these shifts happen before and after the entire division algorithm, +not at each step in the per-digit iteration. + +Note the effect of scaling inputs on the size of the possible quotient. +In the scaled u/v, u can gain a digit from scaling; v never does, because we +pick the scaling factor to make v's top digit larger but without overflowing. +If u and v have n+m and n digits after scaling, then: + + • u < B^(n+m) [B^(n+m) has n+m+1 digits] + • v ≥ B^n / 2 [vₙ₋₁ ≥ B/2, so vₙ₋₁·B^(n-1) ≥ B^n/2] + • u/v < B^(n+m) / (B^n / 2) [divide bounds for u, v] + • u/v < 2 B^m [simplify] + +The quotient can still have m+1 significant digits, but if so the top digit +must be a 1. This provides a different way to handle the first digit of the +result: compare the top n digits of u against v and fill in either a 0 or a 1. + + +Refining Guesses + +Before we check whether u < q̂·v, we can adjust our guess to change it from +q̂ = ⌊uₙuₙ₋₁ / vₙ₋₁⌋ into the refined guess ⌊uₙuₙ₋₁uₙ₋₂ / vₙ₋₁vₙ₋₂⌋. +Although not mentioned above, the Good Guess Guarantee also promises that this +3-by-2-digit division guess is more precise and at most one away from the real +answer q. The improvement from the 2-by-1 to the 3-by-2 guess can also be done +without n-digit math. + +If we have a guess q̂ = ⌊uₙuₙ₋₁ / vₙ₋₁⌋ and we want to see if it also equal to +⌊uₙuₙ₋₁uₙ₋₂ / vₙ₋₁vₙ₋₂⌋, we can use the same check we would for the full division: +if uₙuₙ₋₁uₙ₋₂ < q̂·vₙ₋₁vₙ₋₂, then the guess is too large and should be reduced. + +Checking uₙuₙ₋₁uₙ₋₂ < q̂·vₙ₋₁vₙ₋₂ is the same as uₙuₙ₋₁uₙ₋₂ - q̂·vₙ₋₁vₙ₋₂ < 0, +and + + uₙuₙ₋₁uₙ₋₂ - q̂·vₙ₋₁vₙ₋₂ = (uₙuₙ₋₁·B + uₙ₋₂) - q̂·(vₙ₋₁·B + vₙ₋₂) + [splitting off the bottom digit] + = (uₙuₙ₋₁ - q̂·vₙ₋₁)·B + uₙ₋₂ - q̂·vₙ₋₂ + [regrouping] + +The expression (uₙuₙ₋₁ - q̂·vₙ₋₁) is the remainder of uₙuₙ₋₁ / vₙ₋₁. +If the initial guess returns both q̂ and its remainder r̂, then checking +whether uₙuₙ₋₁uₙ₋₂ < q̂·vₙ₋₁vₙ₋₂ is the same as checking r̂·B + uₙ₋₂ < q̂·vₙ₋₂. + +If we find that r̂·B + uₙ₋₂ < q̂·vₙ₋₂, then we can adjust the guess by +decrementing q̂ and adding vₙ₋₁ to r̂. We repeat until r̂·B + uₙ₋₂ ≥ q̂·vₙ₋₂. +(As before, this fixup is only needed at most twice.) + +Now that q̂ = ⌊uₙuₙ₋₁uₙ₋₂ / vₙ₋₁vₙ₋₂⌋, as mentioned above it is at most one +away from the correct q, and we've avoided doing any n-digit math. +(If we need the new remainder, it can be computed as r̂·B + uₙ₋₂ - q̂·vₙ₋₂.) + +The final check u < q̂·v and the possible fixup must be done at full precision. +For random inputs, a fixup at this step is exceedingly rare: the 3-by-2 guess +is not often wrong at all. But still we must do the check. Note that since the +3-by-2 guess is off by at most 1, it can be convenient to perform the final +u < q̂·v as part of the computation of the remainder r = u - q̂·v. If the +subtraction underflows, decremeting q̂ and adding one v back to r is enough to +arrive at the final q, r. + +That's the entirety of long division: scale the inputs, and then loop over +each output position, guessing, checking, and correcting the next output digit. + +For a 2n-digit number divided by an n-digit number (the worst size-n case for +division complexity), this algorithm uses n+1 iterations, each of which must do +at least the 1-by-n-digit multiplication q̂·v. That's O(n) iterations of +O(n) time each, so O(n²) time overall. + + +Recursive Division + +For very large inputs, it is possible to improve on the O(n²) algorithm. +Let's call a group of n/2 real digits a (very) “wide digit”. We can run the +standard long division algorithm explained above over the wide digits instead of +the actual digits. This will result in many fewer steps, but the math involved in +each step is more work. + +Where basic long division uses a 2-by-1-digit division to guess the initial q̂, +the new algorithm must use a 2-by-1-wide-digit division, which is of course +really an n-by-n/2-digit division. That's OK: if we implement n-digit division +in terms of n/2-digit division, the recursion will terminate when the divisor +becomes small enough to handle with standard long division or even with the +2-by-1 hardware instruction. + +For example, here is a sketch of dividing 10 digits by 4, proceeding with +wide digits corresponding to two regular digits. The first step, still special, +must leave off a (regular) digit, dividing 5 by 4 and producing a 4-digit +remainder less than v. The middle steps divide 6 digits by 4, guaranteed to +produce two output digits each (one wide digit) with 4-digit remainders. +The final step must use what it has: the 4-digit remainder plus one more, +5 digits to divide by 4. + + q₆ q₅ q₄ q₃ q₂ q₁ q₀ + _______________________________ + v₃ v₂ v₁ v₀ ) u₉ u₈ u₇ u₆ u₅ u₄ u₃ u₂ u₁ u₀ + ↓ ↓ ↓ ↓ ↓ | | | | | + [u₉ u₈ u₇ u₆ u₅]| | | | | + - [ q₆q₅·v ]| | | | | + ----------------- ↓ ↓ | | | + [ rem |u₄ u₃]| | | + - [ q₄q₃·v ]| | | + -------------------- ↓ ↓ | + [ rem |u₂ u₁]| + - [ q₂q₁·v ]| + -------------------- ↓ + [ rem |u₀] + - [ q₀·v ] + ------------------ + [ rem ] + +An alternative would be to look ahead to how well n/2 divides into n+m and +adjust the first step to use fewer digits as needed, making the first step +more special to make the last step not special at all. For example, using the +same input, we could choose to use only 4 digits in the first step, leaving +a full wide digit for the last step: + + q₆ q₅ q₄ q₃ q₂ q₁ q₀ + _______________________________ + v₃ v₂ v₁ v₀ ) u₉ u₈ u₇ u₆ u₅ u₄ u₃ u₂ u₁ u₀ + ↓ ↓ ↓ ↓ | | | | | | + [u₉ u₈ u₇ u₆]| | | | | | + - [ q₆·v ]| | | | | | + -------------- ↓ ↓ | | | | + [ rem |u₅ u₄]| | | | + - [ q₅q₄·v ]| | | | + -------------------- ↓ ↓ | | + [ rem |u₃ u₂]| | + - [ q₃q₂·v ]| | + -------------------- ↓ ↓ + [ rem |u₁ u₀] + - [ q₁q₀·v ] + --------------------- + [ rem ] + +Today, the code in divRecursiveStep works like the first example. Perhaps in +the future we will make it work like the alternative, to avoid a special case +in the final iteration. + +Either way, each step is a 3-by-2-wide-digit division approximated first by +a 2-by-1-wide-digit division, just as we did for regular digits in long division. +Because the actual answer we want is a 3-by-2-wide-digit division, instead of +multiplying q̂·v directly during the fixup, we can use the quick refinement +from long division (an n/2-by-n/2 multiply) to correct q to its actual value +and also compute the remainder (as mentioned above), and then stop after that, +never doing a full n-by-n multiply. + +Instead of using an n-by-n/2-digit division to produce n/2 digits, we can add +(not discard) one more real digit, doing an (n+1)-by-(n/2+1)-digit division that +produces n/2+1 digits. That single extra digit tightens the Good Guess Guarantee +to q ≤ q̂ ≤ q+1 and lets us drop long division's special treatment of the first +digit. These benefits are discussed more after the Good Guess Guarantee proof +below. + + +How Fast is Recursive Division? + +For a 2n-by-n-digit division, this algorithm runs a 4-by-2 long division over +wide digits, producing two wide digits plus a possible leading regular digit 1, +which can be handled without a recursive call. That is, the algorithm uses two +full iterations, each using an n-by-n/2-digit division and an n/2-by-n/2-digit +multiplication, along with a few n-digit additions and subtractions. The standard +n-by-n-digit multiplication algorithm requires O(n²) time, making the overall +algorithm require time T(n) where + + T(n) = 2T(n/2) + O(n) + O(n²) + +which, by the Bentley-Haken-Saxe theorem, ends up reducing to T(n) = O(n²). +This is not an improvement over regular long division. + +When the number of digits n becomes large enough, Karatsuba's algorithm for +multiplication can be used instead, which takes O(n^log₂3) = O(n^1.6) time. +(Karatsuba multiplication is implemented in func karatsuba in nat.go.) +That makes the overall recursive division algorithm take O(n^1.6) time as well, +which is an improvement, but again only for large enough numbers. + +It is not critical to make sure that every recursion does only two recursive +calls. While in general the number of recursive calls can change the time +analysis, in this case doing three calls does not change the analysis: + + T(n) = 3T(n/2) + O(n) + O(n^log₂3) + +ends up being T(n) = O(n^log₂3). Because the Karatsuba multiplication taking +time O(n^log₂3) is itself doing 3 half-sized recursions, doing three for the +division does not hurt the asymptotic performance. Of course, it is likely +still faster in practice to do two. + + +Proof of the Good Guess Guarantee + +Given numbers x, y, let us break them into the quotients and remainders when +divided by some scaling factor S, with the added constraints that the quotient +x/y and the high part of y are both less than some limit T, and that the high +part of y is at least half as big as T. + + x₁ = ⌊x/S⌋ y₁ = ⌊y/S⌋ + x₀ = x mod S y₀ = y mod S + + x = x₁·S + x₀ 0 ≤ x₀ < S x/y < T + y = y₁·S + y₀ 0 ≤ y₀ < S T/2 ≤ y₁ < T + +And consider the two truncated quotients: + + q = ⌊x/y⌋ + q̂ = ⌊x₁/y₁⌋ + +We will prove that q ≤ q̂ ≤ q+2. + +The guarantee makes no real demands on the scaling factor S: it is simply the +magnitude of the digits cut from both x and y to produce x₁ and y₁. +The guarantee makes only limited demands on T: it must be large enough to hold +the quotient x/y, and y₁ must have roughly the same size. + +To apply to the earlier discussion of 2-by-1 guesses in long division, +we would choose: + + S = Bⁿ⁻¹ + T = B + x = u + x₁ = uₙuₙ₋₁ + x₀ = uₙ₋₂...u₀ + y = v + y₁ = vₙ₋₁ + y₀ = vₙ₋₂...u₀ + +These simpler variables avoid repeating those longer expressions in the proof. + +Note also that, by definition, truncating division ⌊x/y⌋ satisfies + + x/y - 1 < ⌊x/y⌋ ≤ x/y. + +This fact will be used a few times in the proofs. + +Proof that q ≤ q̂: + + q̂·y₁ = ⌊x₁/y₁⌋·y₁ [by definition, q̂ = ⌊x₁/y₁⌋] + > (x₁/y₁ - 1)·y₁ [x₁/y₁ - 1 < ⌊x₁/y₁⌋] + = x₁ - y₁ [distribute y₁] + + So q̂·y₁ > x₁ - y₁. + Since q̂·y₁ is an integer, q̂·y₁ ≥ x₁ - y₁ + 1. + + q̂ - q = q̂ - ⌊x/y⌋ [by definition, q = ⌊x/y⌋] + ≥ q̂ - x/y [⌊x/y⌋ < x/y] + = (1/y)·(q̂·y - x) [factor out 1/y] + ≥ (1/y)·(q̂·y₁·S - x) [y = y₁·S + y₀ ≥ y₁·S] + ≥ (1/y)·((x₁ - y₁ + 1)·S - x) [above: q̂·y₁ ≥ x₁ - y₁ + 1] + = (1/y)·(x₁·S - y₁·S + S - x) [distribute S] + = (1/y)·(S - x₀ - y₁·S) [-x = -x₁·S - x₀] + > -y₁·S / y [x₀ < S, so S - x₀ < 0; drop it] + ≥ -1 [y₁·S ≤ y] + + So q̂ - q > -1. + Since q̂ - q is an integer, q̂ - q ≥ 0, or equivalently q ≤ q̂. + +Proof that q̂ ≤ q+2: + + x₁/y₁ - x/y = x₁·S/y₁·S - x/y [multiply left term by S/S] + ≤ x/y₁·S - x/y [x₁S ≤ x] + = (x/y)·(y/y₁·S - 1) [factor out x/y] + = (x/y)·((y - y₁·S)/y₁·S) [move -1 into y/y₁·S fraction] + = (x/y)·(y₀/y₁·S) [y - y₁·S = y₀] + = (x/y)·(1/y₁)·(y₀/S) [factor out 1/y₁] + < (x/y)·(1/y₁) [y₀ < S, so y₀/S < 1] + ≤ (x/y)·(2/T) [y₁ ≥ T/2, so 1/y₁ ≤ 2/T] + < T·(2/T) [x/y < T] + = 2 [T·(2/T) = 2] + + So x₁/y₁ - x/y < 2. + + q̂ - q = ⌊x₁/y₁⌋ - q [by definition, q̂ = ⌊x₁/y₁⌋] + = ⌊x₁/y₁⌋ - ⌊x/y⌋ [by definition, q = ⌊x/y⌋] + ≤ x₁/y₁ - ⌊x/y⌋ [⌊x₁/y₁⌋ ≤ x₁/y₁] + < x₁/y₁ - (x/y - 1) [⌊x/y⌋ > x/y - 1] + = (x₁/y₁ - x/y) + 1 [regrouping] + < 2 + 1 [above: x₁/y₁ - x/y < 2] + = 3 + + So q̂ - q < 3. + Since q̂ - q is an integer, q̂ - q ≤ 2. + +Note that when x/y < T/2, the bounds tighten to x₁/y₁ - x/y < 1 and therefore +q̂ - q ≤ 1. + +Note also that in the general case 2n-by-n division where we don't know that +x/y < T, we do know that x/y < 2T, yielding the bound q̂ - q ≤ 4. So we could +remove the special case first step of long division as long as we allow the +first fixup loop to run up to four times. (Using a simple comparison to decide +whether the first digit is 0 or 1 is still more efficient, though.) + +Finally, note that when dividing three leading base-B digits by two (scaled), +we have T = B² and x/y < B = T/B, a much tighter bound than x/y < T. +This in turn yields the much tighter bound x₁/y₁ - x/y < 2/B. This means that +⌊x₁/y₁⌋ and ⌊x/y⌋ can only differ when x/y is less than 2/B greater than an +integer. For random x and y, the chance of this is 2/B, or, for large B, +approximately zero. This means that after we produce the 3-by-2 guess in the +long division algorithm, the fixup loop essentially never runs. + +In the recursive algorithm, the extra digit in (2·⌊n/2⌋+1)-by-(⌊n/2⌋+1)-digit +division has exactly the same effect: the probability of needing a fixup is the +same 2/B. Even better, we can allow the general case x/y < 2T and the fixup +probability only grows to 4/B, still essentially zero. + + +References + +There are no great references for implementing long division; thus this comment. +Here are some notes about what to expect from the obvious references. + +Knuth Volume 2 (Seminumerical Algorithms) section 4.3.1 is the usual canonical +reference for long division, but that entire series is highly compressed, never +repeating a necessary fact and leaving important insights to the exercises. +For example, no rationale whatsoever is given for the calculation that extends +q̂ from a 2-by-1 to a 3-by-2 guess, nor why it reduces the error bound. +The proof that the calculation even has the desired effect is left to exercises. +The solutions to those exercises provided at the back of the book are entirely +calculations, still with no explanation as to what is going on or how you would +arrive at the idea of doing those exact calculations. Nowhere is it mentioned +that this test extends the 2-by-1 guess into a 3-by-2 guess. The proof of the +Good Guess Guarantee is only for the 2-by-1 guess and argues by contradiction, +making it difficult to understand how modifications like adding another digit +or adjusting the quotient range affects the overall bound. + +All that said, Knuth remains the canonical reference. It is dense but packed +full of information and references, and the proofs are simpler than many other +presentations. The proofs above are reworkings of Knuth's to remove the +arguments by contradiction and add explanations or steps that Knuth omitted. +But beware of errors in older printings. Take the published errata with you. + +Brinch Hansen's “Multiple-length Division Revisited: a Tour of the Minefield” +starts with a blunt critique of Knuth's presentation (among others) and then +presents a more detailed and easier to follow treatment of long division, +including an implementation in Pascal. But the algorithm and implementation +work entirely in terms of 3-by-2 division, which is much less useful on modern +hardware than an algorithm using 2-by-1 division. The proofs are a bit too +focused on digit counting and seem needlessly complex, especially compared to +the ones given above. + +Burnikel and Ziegler's “Fast Recursive Division” introduced the key insight of +implementing division by an n-digit divisor using recursive calls to division +by an n/2-digit divisor, relying on Karatsuba multiplication to yield a +sub-quadratic run time. However, the presentation decisions are made almost +entirely for the purpose of simplifying the run-time analysis, rather than +simplifying the presentation. Instead of a single algorithm that loops over +quotient digits, the paper presents two mutually-recursive algorithms, for +2n-by-n and 3n-by-2n. The paper also does not present any general (n+m)-by-n +algorithm. + +The proofs in the paper are remarkably complex, especially considering that +the algorithm is at its core just long division on wide digits, so that the +usual long division proofs apply essentially unaltered. +*/ + +package big + +import "math/bits" + +// div returns q, r such that q = ⌊u/v⌋ and r = u%v = u - q·v. +// It uses z and z2 as the storage for q and r. +func (z nat) div(z2, u, v nat) (q, r nat) { + if len(v) == 0 { + panic("division by zero") + } + + if u.cmp(v) < 0 { + q = z[:0] + r = z2.set(u) + return + } + + if len(v) == 1 { + // Short division: long optimized for a single-word divisor. + // In that case, the 2-by-1 guess is all we need at each step. + var r2 Word + q, r2 = z.divW(u, v[0]) + r = z2.setWord(r2) + return + } + + q, r = z.divLarge(z2, u, v) + return +} + +// divW returns q, r such that q = ⌊x/y⌋ and r = x%y = x - q·y. +// It uses z as the storage for q. +// Note that y is a single digit (Word), not a big number. +func (z nat) divW(x nat, y Word) (q nat, r Word) { + m := len(x) + switch { + case y == 0: + panic("division by zero") + case y == 1: + q = z.set(x) // result is x + return + case m == 0: + q = z[:0] // result is 0 + return + } + // m > 0 + z = z.make(m) + r = divWVW(z, 0, x, y) + q = z.norm() + return +} + +// modW returns x % d. +func (x nat) modW(d Word) (r Word) { + // TODO(agl): we don't actually need to store the q value. + var q nat + q = q.make(len(x)) + return divWVW(q, 0, x, d) +} + +// divWVW overwrites z with ⌊x/y⌋, returning the remainder r. +// The caller must ensure that len(z) = len(x). +func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) { + r = xn + if len(x) == 1 { + qq, rr := bits.Div(uint(r), uint(x[0]), uint(y)) + z[0] = Word(qq) + return Word(rr) + } + rec := reciprocalWord(y) + for i := len(z) - 1; i >= 0; i-- { + z[i], r = divWW(r, x[i], y, rec) + } + return r +} + +// div returns q, r such that q = ⌊uIn/vIn⌋ and r = uIn%vIn = uIn - q·vIn. +// It uses z and u as the storage for q and r. +// The caller must ensure that len(vIn) ≥ 2 (use divW otherwise) +// and that len(uIn) ≥ len(vIn) (the answer is 0, uIn otherwise). +func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) { + n := len(vIn) + m := len(uIn) - n + + // Scale the inputs so vIn's top bit is 1 (see “Scaling Inputs” above). + // vIn is treated as a read-only input (it may be in use by another + // goroutine), so we must make a copy. + // uIn is copied to u. + shift := nlz(vIn[n-1]) + vp := getNat(n) + v := *vp + shlVU(v, vIn, shift) + u = u.make(len(uIn) + 1) + u[len(uIn)] = shlVU(u[0:len(uIn)], uIn, shift) + + // The caller should not pass aliased z and u, since those are + // the two different outputs, but correct just in case. + if alias(z, u) { + z = nil + } + q = z.make(m + 1) + + // Use basic or recursive long division depending on size. + if n < divRecursiveThreshold { + q.divBasic(u, v) + } else { + q.divRecursive(u, v) + } + putNat(vp) + + q = q.norm() + + // Undo scaling of remainder. + shrVU(u, u, shift) + r = u.norm() + + return q, r +} + +// divBasic implements long division as described above. +// It overwrites q with ⌊u/v⌋ and overwrites u with the remainder r. +// q must be large enough to hold ⌊u/v⌋. +func (q nat) divBasic(u, v nat) { + n := len(v) + m := len(u) - n + + qhatvp := getNat(n + 1) + qhatv := *qhatvp + + // Set up for divWW below, precomputing reciprocal argument. + vn1 := v[n-1] + rec := reciprocalWord(vn1) + + // Compute each digit of quotient. + for j := m; j >= 0; j-- { + // Compute the 2-by-1 guess q̂. + // The first iteration must invent a leading 0 for u. + qhat := Word(_M) + var ujn Word + if j+n < len(u) { + ujn = u[j+n] + } + + // ujn ≤ vn1, or else q̂ would be more than one digit. + // For ujn == vn1, we set q̂ to the max digit M above. + // Otherwise, we compute the 2-by-1 guess. + if ujn != vn1 { + var rhat Word + qhat, rhat = divWW(ujn, u[j+n-1], vn1, rec) + + // Refine q̂ to a 3-by-2 guess. See “Refining Guesses” above. + vn2 := v[n-2] + x1, x2 := mulWW(qhat, vn2) + ujn2 := u[j+n-2] + for greaterThan(x1, x2, rhat, ujn2) { // x1x2 > r̂ u[j+n-2] + qhat-- + prevRhat := rhat + rhat += vn1 + // If r̂ overflows, then + // r̂ u[j+n-2]v[n-1] is now definitely > x1 x2. + if rhat < prevRhat { + break + } + // TODO(rsc): No need for a full mulWW. + // x2 += vn2; if x2 overflows, x1++ + x1, x2 = mulWW(qhat, vn2) + } + } + + // Compute q̂·v. + qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0) + qhl := len(qhatv) + if j+qhl > len(u) && qhatv[n] == 0 { + qhl-- + } + + // Subtract q̂·v from the current section of u. + // If it underflows, q̂·v > u, which we fix up + // by decrementing q̂ and adding v back. + c := subVV(u[j:j+qhl], u[j:], qhatv) + if c != 0 { + c := addVV(u[j:j+n], u[j:], v) + // If n == qhl, the carry from subVV and the carry from addVV + // cancel out and don't affect u[j+n]. + if n < qhl { + u[j+n] += c + } + qhat-- + } + + // Save quotient digit. + // Caller may know the top digit is zero and not leave room for it. + if j == m && m == len(q) && qhat == 0 { + continue + } + q[j] = qhat + } + + putNat(qhatvp) +} + +// greaterThan reports whether the two digit numbers x1 x2 > y1 y2. +// TODO(rsc): In contradiction to most of this file, x1 is the high +// digit and x2 is the low digit. This should be fixed. +func greaterThan(x1, x2, y1, y2 Word) bool { + return x1 > y1 || x1 == y1 && x2 > y2 +} + +// divRecursiveThreshold is the number of divisor digits +// at which point divRecursive is faster than divBasic. +const divRecursiveThreshold = 100 + +// divRecursive implements recursive division as described above. +// It overwrites z with ⌊u/v⌋ and overwrites u with the remainder r. +// z must be large enough to hold ⌊u/v⌋. +// This function is just for allocating and freeing temporaries +// around divRecursiveStep, the real implementation. +func (z nat) divRecursive(u, v nat) { + // Recursion depth is (much) less than 2 log₂(len(v)). + // Allocate a slice of temporaries to be reused across recursion, + // plus one extra temporary not live across the recursion. + recDepth := 2 * bits.Len(uint(len(v))) + tmp := getNat(3 * len(v)) + temps := make([]*nat, recDepth) + + z.clear() + z.divRecursiveStep(u, v, 0, tmp, temps) + + // Free temporaries. + for _, n := range temps { + if n != nil { + putNat(n) + } + } + putNat(tmp) +} + +// divRecursiveStep is the actual implementation of recursive division. +// It adds ⌊u/v⌋ to z and overwrites u with the remainder r. +// z must be large enough to hold ⌊u/v⌋. +// It uses temps[depth] (allocating if needed) as a temporary live across +// the recursive call. It also uses tmp, but not live across the recursion. +func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) { + // u is a subsection of the original and may have leading zeros. + // TODO(rsc): The v = v.norm() is useless and should be removed. + // We know (and require) that v's top digit is ≥ B/2. + u = u.norm() + v = v.norm() + if len(u) == 0 { + z.clear() + return + } + + // Fall back to basic division if the problem is now small enough. + n := len(v) + if n < divRecursiveThreshold { + z.divBasic(u, v) + return + } + + // Nothing to do if u is shorter than v (implies u < v). + m := len(u) - n + if m < 0 { + return + } + + // We consider B digits in a row as a single wide digit. + // (See “Recursive Division” above.) + // + // TODO(rsc): rename B to Wide, to avoid confusion with _B, + // which is something entirely different. + // TODO(rsc): Look into whether using ⌈n/2⌉ is better than ⌊n/2⌋. + B := n / 2 + + // Allocate a nat for qhat below. + if temps[depth] == nil { + temps[depth] = getNat(n) // TODO(rsc): Can be just B+1. + } else { + *temps[depth] = temps[depth].make(B + 1) + } + + // Compute each wide digit of the quotient. + // + // TODO(rsc): Change the loop to be + // for j := (m+B-1)/B*B; j > 0; j -= B { + // which will make the final step a regular step, letting us + // delete what amounts to an extra copy of the loop body below. + j := m + for j > B { + // Divide u[j-B:j+n] (3 wide digits) by v (2 wide digits). + // First make the 2-by-1-wide-digit guess using a recursive call. + // Then extend the guess to the full 3-by-2 (see “Refining Guesses”). + // + // For the 2-by-1-wide-digit guess, instead of doing 2B-by-B-digit, + // we use a (2B+1)-by-(B+1) digit, which handles the possibility that + // the result has an extra leading 1 digit as well as guaranteeing + // that the computed q̂ will be off by at most 1 instead of 2. + + // s is the number of digits to drop from the 3B- and 2B-digit chunks. + // We drop B-1 to be left with 2B+1 and B+1. + s := (B - 1) + + // uu is the up-to-3B-digit section of u we are working on. + uu := u[j-B:] + + // Compute the 2-by-1 guess q̂, leaving r̂ in uu[s:B+n]. + qhat := *temps[depth] + qhat.clear() + qhat.divRecursiveStep(uu[s:B+n], v[s:], depth+1, tmp, temps) + qhat = qhat.norm() + + // Extend to a 3-by-2 quotient and remainder. + // Because divRecursiveStep overwrote the top part of uu with + // the remainder r̂, the full uu already contains the equivalent + // of r̂·B + uₙ₋₂ from the “Refining Guesses” discussion. + // Subtracting q̂·vₙ₋₂ from it will compute the full-length remainder. + // If that subtraction underflows, q̂·v > u, which we fix up + // by decrementing q̂ and adding v back, same as in long division. + + // TODO(rsc): Instead of subtract and fix-up, this code is computing + // q̂·vₙ₋₂ and decrementing q̂ until that product is ≤ u. + // But we can do the subtraction directly, as in the comment above + // and in long division, because we know that q̂ is wrong by at most one. + qhatv := tmp.make(3 * n) + qhatv.clear() + qhatv = qhatv.mul(qhat, v[:s]) + for i := 0; i < 2; i++ { + e := qhatv.cmp(uu.norm()) + if e <= 0 { + break + } + subVW(qhat, qhat, 1) + c := subVV(qhatv[:s], qhatv[:s], v[:s]) + if len(qhatv) > s { + subVW(qhatv[s:], qhatv[s:], c) + } + addAt(uu[s:], v[s:], 0) + } + if qhatv.cmp(uu.norm()) > 0 { + panic("impossible") + } + c := subVV(uu[:len(qhatv)], uu[:len(qhatv)], qhatv) + if c > 0 { + subVW(uu[len(qhatv):], uu[len(qhatv):], c) + } + addAt(z, qhat, j-B) + j -= B + } + + // TODO(rsc): Rewrite loop as described above and delete all this code. + + // Now u < (v<<B), compute lower bits in the same way. + // Choose shift = B-1 again. + s := B - 1 + qhat := *temps[depth] + qhat.clear() + qhat.divRecursiveStep(u[s:].norm(), v[s:], depth+1, tmp, temps) + qhat = qhat.norm() + qhatv := tmp.make(3 * n) + qhatv.clear() + qhatv = qhatv.mul(qhat, v[:s]) + // Set the correct remainder as before. + for i := 0; i < 2; i++ { + if e := qhatv.cmp(u.norm()); e > 0 { + subVW(qhat, qhat, 1) + c := subVV(qhatv[:s], qhatv[:s], v[:s]) + if len(qhatv) > s { + subVW(qhatv[s:], qhatv[s:], c) + } + addAt(u[s:], v[s:], 0) + } + } + if qhatv.cmp(u.norm()) > 0 { + panic("impossible") + } + c := subVV(u[0:len(qhatv)], u[0:len(qhatv)], qhatv) + if c > 0 { + c = subVW(u[len(qhatv):], u[len(qhatv):], c) + } + if c > 0 { + panic("impossible") + } + + // Done! + addAt(z, qhat.norm(), 0) +} diff --git a/contrib/go/_std_1.18/src/math/big/prime.go b/contrib/go/_std_1.18/src/math/big/prime.go new file mode 100644 index 0000000000..d9a5f1ec96 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/prime.go @@ -0,0 +1,320 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package big + +import "math/rand" + +// ProbablyPrime reports whether x is probably prime, +// applying the Miller-Rabin test with n pseudorandomly chosen bases +// as well as a Baillie-PSW test. +// +// If x is prime, ProbablyPrime returns true. +// If x is chosen randomly and not prime, ProbablyPrime probably returns false. +// The probability of returning true for a randomly chosen non-prime is at most ¼ⁿ. +// +// ProbablyPrime is 100% accurate for inputs less than 2⁶⁴. +// See Menezes et al., Handbook of Applied Cryptography, 1997, pp. 145-149, +// and FIPS 186-4 Appendix F for further discussion of the error probabilities. +// +// ProbablyPrime is not suitable for judging primes that an adversary may +// have crafted to fool the test. +// +// As of Go 1.8, ProbablyPrime(0) is allowed and applies only a Baillie-PSW test. +// Before Go 1.8, ProbablyPrime applied only the Miller-Rabin tests, and ProbablyPrime(0) panicked. +func (x *Int) ProbablyPrime(n int) bool { + // Note regarding the doc comment above: + // It would be more precise to say that the Baillie-PSW test uses the + // extra strong Lucas test as its Lucas test, but since no one knows + // how to tell any of the Lucas tests apart inside a Baillie-PSW test + // (they all work equally well empirically), that detail need not be + // documented or implicitly guaranteed. + // The comment does avoid saying "the" Baillie-PSW test + // because of this general ambiguity. + + if n < 0 { + panic("negative n for ProbablyPrime") + } + if x.neg || len(x.abs) == 0 { + return false + } + + // primeBitMask records the primes < 64. + const primeBitMask uint64 = 1<<2 | 1<<3 | 1<<5 | 1<<7 | + 1<<11 | 1<<13 | 1<<17 | 1<<19 | 1<<23 | 1<<29 | 1<<31 | + 1<<37 | 1<<41 | 1<<43 | 1<<47 | 1<<53 | 1<<59 | 1<<61 + + w := x.abs[0] + if len(x.abs) == 1 && w < 64 { + return primeBitMask&(1<<w) != 0 + } + + if w&1 == 0 { + return false // x is even + } + + const primesA = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 37 + const primesB = 29 * 31 * 41 * 43 * 47 * 53 + + var rA, rB uint32 + switch _W { + case 32: + rA = uint32(x.abs.modW(primesA)) + rB = uint32(x.abs.modW(primesB)) + case 64: + r := x.abs.modW((primesA * primesB) & _M) + rA = uint32(r % primesA) + rB = uint32(r % primesB) + default: + panic("math/big: invalid word size") + } + + if rA%3 == 0 || rA%5 == 0 || rA%7 == 0 || rA%11 == 0 || rA%13 == 0 || rA%17 == 0 || rA%19 == 0 || rA%23 == 0 || rA%37 == 0 || + rB%29 == 0 || rB%31 == 0 || rB%41 == 0 || rB%43 == 0 || rB%47 == 0 || rB%53 == 0 { + return false + } + + return x.abs.probablyPrimeMillerRabin(n+1, true) && x.abs.probablyPrimeLucas() +} + +// probablyPrimeMillerRabin reports whether n passes reps rounds of the +// Miller-Rabin primality test, using pseudo-randomly chosen bases. +// If force2 is true, one of the rounds is forced to use base 2. +// See Handbook of Applied Cryptography, p. 139, Algorithm 4.24. +// The number n is known to be non-zero. +func (n nat) probablyPrimeMillerRabin(reps int, force2 bool) bool { + nm1 := nat(nil).sub(n, natOne) + // determine q, k such that nm1 = q << k + k := nm1.trailingZeroBits() + q := nat(nil).shr(nm1, k) + + nm3 := nat(nil).sub(nm1, natTwo) + rand := rand.New(rand.NewSource(int64(n[0]))) + + var x, y, quotient nat + nm3Len := nm3.bitLen() + +NextRandom: + for i := 0; i < reps; i++ { + if i == reps-1 && force2 { + x = x.set(natTwo) + } else { + x = x.random(rand, nm3, nm3Len) + x = x.add(x, natTwo) + } + y = y.expNN(x, q, n) + if y.cmp(natOne) == 0 || y.cmp(nm1) == 0 { + continue + } + for j := uint(1); j < k; j++ { + y = y.sqr(y) + quotient, y = quotient.div(y, y, n) + if y.cmp(nm1) == 0 { + continue NextRandom + } + if y.cmp(natOne) == 0 { + return false + } + } + return false + } + + return true +} + +// probablyPrimeLucas reports whether n passes the "almost extra strong" Lucas probable prime test, +// using Baillie-OEIS parameter selection. This corresponds to "AESLPSP" on Jacobsen's tables (link below). +// The combination of this test and a Miller-Rabin/Fermat test with base 2 gives a Baillie-PSW test. +// +// References: +// +// Baillie and Wagstaff, "Lucas Pseudoprimes", Mathematics of Computation 35(152), +// October 1980, pp. 1391-1417, especially page 1401. +// https://www.ams.org/journals/mcom/1980-35-152/S0025-5718-1980-0583518-6/S0025-5718-1980-0583518-6.pdf +// +// Grantham, "Frobenius Pseudoprimes", Mathematics of Computation 70(234), +// March 2000, pp. 873-891. +// https://www.ams.org/journals/mcom/2001-70-234/S0025-5718-00-01197-2/S0025-5718-00-01197-2.pdf +// +// Baillie, "Extra strong Lucas pseudoprimes", OEIS A217719, https://oeis.org/A217719. +// +// Jacobsen, "Pseudoprime Statistics, Tables, and Data", http://ntheory.org/pseudoprimes.html. +// +// Nicely, "The Baillie-PSW Primality Test", http://www.trnicely.net/misc/bpsw.html. +// (Note that Nicely's definition of the "extra strong" test gives the wrong Jacobi condition, +// as pointed out by Jacobsen.) +// +// Crandall and Pomerance, Prime Numbers: A Computational Perspective, 2nd ed. +// Springer, 2005. +func (n nat) probablyPrimeLucas() bool { + // Discard 0, 1. + if len(n) == 0 || n.cmp(natOne) == 0 { + return false + } + // Two is the only even prime. + // Already checked by caller, but here to allow testing in isolation. + if n[0]&1 == 0 { + return n.cmp(natTwo) == 0 + } + + // Baillie-OEIS "method C" for choosing D, P, Q, + // as in https://oeis.org/A217719/a217719.txt: + // try increasing P ≥ 3 such that D = P² - 4 (so Q = 1) + // until Jacobi(D, n) = -1. + // The search is expected to succeed for non-square n after just a few trials. + // After more than expected failures, check whether n is square + // (which would cause Jacobi(D, n) = 1 for all D not dividing n). + p := Word(3) + d := nat{1} + t1 := nat(nil) // temp + intD := &Int{abs: d} + intN := &Int{abs: n} + for ; ; p++ { + if p > 10000 { + // This is widely believed to be impossible. + // If we get a report, we'll want the exact number n. + panic("math/big: internal error: cannot find (D/n) = -1 for " + intN.String()) + } + d[0] = p*p - 4 + j := Jacobi(intD, intN) + if j == -1 { + break + } + if j == 0 { + // d = p²-4 = (p-2)(p+2). + // If (d/n) == 0 then d shares a prime factor with n. + // Since the loop proceeds in increasing p and starts with p-2==1, + // the shared prime factor must be p+2. + // If p+2 == n, then n is prime; otherwise p+2 is a proper factor of n. + return len(n) == 1 && n[0] == p+2 + } + if p == 40 { + // We'll never find (d/n) = -1 if n is a square. + // If n is a non-square we expect to find a d in just a few attempts on average. + // After 40 attempts, take a moment to check if n is indeed a square. + t1 = t1.sqrt(n) + t1 = t1.sqr(t1) + if t1.cmp(n) == 0 { + return false + } + } + } + + // Grantham definition of "extra strong Lucas pseudoprime", after Thm 2.3 on p. 876 + // (D, P, Q above have become Δ, b, 1): + // + // Let U_n = U_n(b, 1), V_n = V_n(b, 1), and Δ = b²-4. + // An extra strong Lucas pseudoprime to base b is a composite n = 2^r s + Jacobi(Δ, n), + // where s is odd and gcd(n, 2*Δ) = 1, such that either (i) U_s ≡ 0 mod n and V_s ≡ ±2 mod n, + // or (ii) V_{2^t s} ≡ 0 mod n for some 0 ≤ t < r-1. + // + // We know gcd(n, Δ) = 1 or else we'd have found Jacobi(d, n) == 0 above. + // We know gcd(n, 2) = 1 because n is odd. + // + // Arrange s = (n - Jacobi(Δ, n)) / 2^r = (n+1) / 2^r. + s := nat(nil).add(n, natOne) + r := int(s.trailingZeroBits()) + s = s.shr(s, uint(r)) + nm2 := nat(nil).sub(n, natTwo) // n-2 + + // We apply the "almost extra strong" test, which checks the above conditions + // except for U_s ≡ 0 mod n, which allows us to avoid computing any U_k values. + // Jacobsen points out that maybe we should just do the full extra strong test: + // "It is also possible to recover U_n using Crandall and Pomerance equation 3.13: + // U_n = D^-1 (2V_{n+1} - PV_n) allowing us to run the full extra-strong test + // at the cost of a single modular inversion. This computation is easy and fast in GMP, + // so we can get the full extra-strong test at essentially the same performance as the + // almost extra strong test." + + // Compute Lucas sequence V_s(b, 1), where: + // + // V(0) = 2 + // V(1) = P + // V(k) = P V(k-1) - Q V(k-2). + // + // (Remember that due to method C above, P = b, Q = 1.) + // + // In general V(k) = α^k + β^k, where α and β are roots of x² - Px + Q. + // Crandall and Pomerance (p.147) observe that for 0 ≤ j ≤ k, + // + // V(j+k) = V(j)V(k) - V(k-j). + // + // So in particular, to quickly double the subscript: + // + // V(2k) = V(k)² - 2 + // V(2k+1) = V(k) V(k+1) - P + // + // We can therefore start with k=0 and build up to k=s in log₂(s) steps. + natP := nat(nil).setWord(p) + vk := nat(nil).setWord(2) + vk1 := nat(nil).setWord(p) + t2 := nat(nil) // temp + for i := int(s.bitLen()); i >= 0; i-- { + if s.bit(uint(i)) != 0 { + // k' = 2k+1 + // V(k') = V(2k+1) = V(k) V(k+1) - P. + t1 = t1.mul(vk, vk1) + t1 = t1.add(t1, n) + t1 = t1.sub(t1, natP) + t2, vk = t2.div(vk, t1, n) + // V(k'+1) = V(2k+2) = V(k+1)² - 2. + t1 = t1.sqr(vk1) + t1 = t1.add(t1, nm2) + t2, vk1 = t2.div(vk1, t1, n) + } else { + // k' = 2k + // V(k'+1) = V(2k+1) = V(k) V(k+1) - P. + t1 = t1.mul(vk, vk1) + t1 = t1.add(t1, n) + t1 = t1.sub(t1, natP) + t2, vk1 = t2.div(vk1, t1, n) + // V(k') = V(2k) = V(k)² - 2 + t1 = t1.sqr(vk) + t1 = t1.add(t1, nm2) + t2, vk = t2.div(vk, t1, n) + } + } + + // Now k=s, so vk = V(s). Check V(s) ≡ ±2 (mod n). + if vk.cmp(natTwo) == 0 || vk.cmp(nm2) == 0 { + // Check U(s) ≡ 0. + // As suggested by Jacobsen, apply Crandall and Pomerance equation 3.13: + // + // U(k) = D⁻¹ (2 V(k+1) - P V(k)) + // + // Since we are checking for U(k) == 0 it suffices to check 2 V(k+1) == P V(k) mod n, + // or P V(k) - 2 V(k+1) == 0 mod n. + t1 := t1.mul(vk, natP) + t2 := t2.shl(vk1, 1) + if t1.cmp(t2) < 0 { + t1, t2 = t2, t1 + } + t1 = t1.sub(t1, t2) + t3 := vk1 // steal vk1, no longer needed below + vk1 = nil + _ = vk1 + t2, t3 = t2.div(t3, t1, n) + if len(t3) == 0 { + return true + } + } + + // Check V(2^t s) ≡ 0 mod n for some 0 ≤ t < r-1. + for t := 0; t < r-1; t++ { + if len(vk) == 0 { // vk == 0 + return true + } + // Optimization: V(k) = 2 is a fixed point for V(k') = V(k)² - 2, + // so if V(k) = 2, we can stop: we will never find a future V(k) == 0. + if len(vk) == 1 && vk[0] == 2 { // vk == 2 + return false + } + // k' = 2k + // V(k') = V(2k) = V(k)² - 2 + t1 = t1.sqr(vk) + t1 = t1.sub(t1, natTwo) + t2, vk = t2.div(vk, t1, n) + } + return false +} diff --git a/contrib/go/_std_1.18/src/math/big/rat.go b/contrib/go/_std_1.18/src/math/big/rat.go new file mode 100644 index 0000000000..731a979ff7 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/rat.go @@ -0,0 +1,544 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements multi-precision rational numbers. + +package big + +import ( + "fmt" + "math" +) + +// A Rat represents a quotient a/b of arbitrary precision. +// The zero value for a Rat represents the value 0. +// +// Operations always take pointer arguments (*Rat) rather +// than Rat values, and each unique Rat value requires +// its own unique *Rat pointer. To "copy" a Rat value, +// an existing (or newly allocated) Rat must be set to +// a new value using the Rat.Set method; shallow copies +// of Rats are not supported and may lead to errors. +type Rat struct { + // To make zero values for Rat work w/o initialization, + // a zero value of b (len(b) == 0) acts like b == 1. At + // the earliest opportunity (when an assignment to the Rat + // is made), such uninitialized denominators are set to 1. + // a.neg determines the sign of the Rat, b.neg is ignored. + a, b Int +} + +// NewRat creates a new Rat with numerator a and denominator b. +func NewRat(a, b int64) *Rat { + return new(Rat).SetFrac64(a, b) +} + +// SetFloat64 sets z to exactly f and returns z. +// If f is not finite, SetFloat returns nil. +func (z *Rat) SetFloat64(f float64) *Rat { + const expMask = 1<<11 - 1 + bits := math.Float64bits(f) + mantissa := bits & (1<<52 - 1) + exp := int((bits >> 52) & expMask) + switch exp { + case expMask: // non-finite + return nil + case 0: // denormal + exp -= 1022 + default: // normal + mantissa |= 1 << 52 + exp -= 1023 + } + + shift := 52 - exp + + // Optimization (?): partially pre-normalise. + for mantissa&1 == 0 && shift > 0 { + mantissa >>= 1 + shift-- + } + + z.a.SetUint64(mantissa) + z.a.neg = f < 0 + z.b.Set(intOne) + if shift > 0 { + z.b.Lsh(&z.b, uint(shift)) + } else { + z.a.Lsh(&z.a, uint(-shift)) + } + return z.norm() +} + +// quotToFloat32 returns the non-negative float32 value +// nearest to the quotient a/b, using round-to-even in +// halfway cases. It does not mutate its arguments. +// Preconditions: b is non-zero; a and b have no common factors. +func quotToFloat32(a, b nat) (f float32, exact bool) { + const ( + // float size in bits + Fsize = 32 + + // mantissa + Msize = 23 + Msize1 = Msize + 1 // incl. implicit 1 + Msize2 = Msize1 + 1 + + // exponent + Esize = Fsize - Msize1 + Ebias = 1<<(Esize-1) - 1 + Emin = 1 - Ebias + Emax = Ebias + ) + + // TODO(adonovan): specialize common degenerate cases: 1.0, integers. + alen := a.bitLen() + if alen == 0 { + return 0, true + } + blen := b.bitLen() + if blen == 0 { + panic("division by zero") + } + + // 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1) + // (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B). + // This is 2 or 3 more than the float32 mantissa field width of Msize: + // - the optional extra bit is shifted away in step 3 below. + // - the high-order 1 is omitted in "normal" representation; + // - the low-order 1 will be used during rounding then discarded. + exp := alen - blen + var a2, b2 nat + a2 = a2.set(a) + b2 = b2.set(b) + if shift := Msize2 - exp; shift > 0 { + a2 = a2.shl(a2, uint(shift)) + } else if shift < 0 { + b2 = b2.shl(b2, uint(-shift)) + } + + // 2. Compute quotient and remainder (q, r). NB: due to the + // extra shift, the low-order bit of q is logically the + // high-order bit of r. + var q nat + q, r := q.div(a2, a2, b2) // (recycle a2) + mantissa := low32(q) + haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half + + // 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1 + // (in effect---we accomplish this incrementally). + if mantissa>>Msize2 == 1 { + if mantissa&1 == 1 { + haveRem = true + } + mantissa >>= 1 + exp++ + } + if mantissa>>Msize1 != 1 { + panic(fmt.Sprintf("expected exactly %d bits of result", Msize2)) + } + + // 4. Rounding. + if Emin-Msize <= exp && exp <= Emin { + // Denormal case; lose 'shift' bits of precision. + shift := uint(Emin - (exp - 1)) // [1..Esize1) + lostbits := mantissa & (1<<shift - 1) + haveRem = haveRem || lostbits != 0 + mantissa >>= shift + exp = 2 - Ebias // == exp + shift + } + // Round q using round-half-to-even. + exact = !haveRem + if mantissa&1 != 0 { + exact = false + if haveRem || mantissa&2 != 0 { + if mantissa++; mantissa >= 1<<Msize2 { + // Complete rollover 11...1 => 100...0, so shift is safe + mantissa >>= 1 + exp++ + } + } + } + mantissa >>= 1 // discard rounding bit. Mantissa now scaled by 1<<Msize1. + + f = float32(math.Ldexp(float64(mantissa), exp-Msize1)) + if math.IsInf(float64(f), 0) { + exact = false + } + return +} + +// quotToFloat64 returns the non-negative float64 value +// nearest to the quotient a/b, using round-to-even in +// halfway cases. It does not mutate its arguments. +// Preconditions: b is non-zero; a and b have no common factors. +func quotToFloat64(a, b nat) (f float64, exact bool) { + const ( + // float size in bits + Fsize = 64 + + // mantissa + Msize = 52 + Msize1 = Msize + 1 // incl. implicit 1 + Msize2 = Msize1 + 1 + + // exponent + Esize = Fsize - Msize1 + Ebias = 1<<(Esize-1) - 1 + Emin = 1 - Ebias + Emax = Ebias + ) + + // TODO(adonovan): specialize common degenerate cases: 1.0, integers. + alen := a.bitLen() + if alen == 0 { + return 0, true + } + blen := b.bitLen() + if blen == 0 { + panic("division by zero") + } + + // 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1) + // (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B). + // This is 2 or 3 more than the float64 mantissa field width of Msize: + // - the optional extra bit is shifted away in step 3 below. + // - the high-order 1 is omitted in "normal" representation; + // - the low-order 1 will be used during rounding then discarded. + exp := alen - blen + var a2, b2 nat + a2 = a2.set(a) + b2 = b2.set(b) + if shift := Msize2 - exp; shift > 0 { + a2 = a2.shl(a2, uint(shift)) + } else if shift < 0 { + b2 = b2.shl(b2, uint(-shift)) + } + + // 2. Compute quotient and remainder (q, r). NB: due to the + // extra shift, the low-order bit of q is logically the + // high-order bit of r. + var q nat + q, r := q.div(a2, a2, b2) // (recycle a2) + mantissa := low64(q) + haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half + + // 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1 + // (in effect---we accomplish this incrementally). + if mantissa>>Msize2 == 1 { + if mantissa&1 == 1 { + haveRem = true + } + mantissa >>= 1 + exp++ + } + if mantissa>>Msize1 != 1 { + panic(fmt.Sprintf("expected exactly %d bits of result", Msize2)) + } + + // 4. Rounding. + if Emin-Msize <= exp && exp <= Emin { + // Denormal case; lose 'shift' bits of precision. + shift := uint(Emin - (exp - 1)) // [1..Esize1) + lostbits := mantissa & (1<<shift - 1) + haveRem = haveRem || lostbits != 0 + mantissa >>= shift + exp = 2 - Ebias // == exp + shift + } + // Round q using round-half-to-even. + exact = !haveRem + if mantissa&1 != 0 { + exact = false + if haveRem || mantissa&2 != 0 { + if mantissa++; mantissa >= 1<<Msize2 { + // Complete rollover 11...1 => 100...0, so shift is safe + mantissa >>= 1 + exp++ + } + } + } + mantissa >>= 1 // discard rounding bit. Mantissa now scaled by 1<<Msize1. + + f = math.Ldexp(float64(mantissa), exp-Msize1) + if math.IsInf(f, 0) { + exact = false + } + return +} + +// Float32 returns the nearest float32 value for x and a bool indicating +// whether f represents x exactly. If the magnitude of x is too large to +// be represented by a float32, f is an infinity and exact is false. +// The sign of f always matches the sign of x, even if f == 0. +func (x *Rat) Float32() (f float32, exact bool) { + b := x.b.abs + if len(b) == 0 { + b = natOne + } + f, exact = quotToFloat32(x.a.abs, b) + if x.a.neg { + f = -f + } + return +} + +// Float64 returns the nearest float64 value for x and a bool indicating +// whether f represents x exactly. If the magnitude of x is too large to +// be represented by a float64, f is an infinity and exact is false. +// The sign of f always matches the sign of x, even if f == 0. +func (x *Rat) Float64() (f float64, exact bool) { + b := x.b.abs + if len(b) == 0 { + b = natOne + } + f, exact = quotToFloat64(x.a.abs, b) + if x.a.neg { + f = -f + } + return +} + +// SetFrac sets z to a/b and returns z. +// If b == 0, SetFrac panics. +func (z *Rat) SetFrac(a, b *Int) *Rat { + z.a.neg = a.neg != b.neg + babs := b.abs + if len(babs) == 0 { + panic("division by zero") + } + if &z.a == b || alias(z.a.abs, babs) { + babs = nat(nil).set(babs) // make a copy + } + z.a.abs = z.a.abs.set(a.abs) + z.b.abs = z.b.abs.set(babs) + return z.norm() +} + +// SetFrac64 sets z to a/b and returns z. +// If b == 0, SetFrac64 panics. +func (z *Rat) SetFrac64(a, b int64) *Rat { + if b == 0 { + panic("division by zero") + } + z.a.SetInt64(a) + if b < 0 { + b = -b + z.a.neg = !z.a.neg + } + z.b.abs = z.b.abs.setUint64(uint64(b)) + return z.norm() +} + +// SetInt sets z to x (by making a copy of x) and returns z. +func (z *Rat) SetInt(x *Int) *Rat { + z.a.Set(x) + z.b.abs = z.b.abs.setWord(1) + return z +} + +// SetInt64 sets z to x and returns z. +func (z *Rat) SetInt64(x int64) *Rat { + z.a.SetInt64(x) + z.b.abs = z.b.abs.setWord(1) + return z +} + +// SetUint64 sets z to x and returns z. +func (z *Rat) SetUint64(x uint64) *Rat { + z.a.SetUint64(x) + z.b.abs = z.b.abs.setWord(1) + return z +} + +// Set sets z to x (by making a copy of x) and returns z. +func (z *Rat) Set(x *Rat) *Rat { + if z != x { + z.a.Set(&x.a) + z.b.Set(&x.b) + } + if len(z.b.abs) == 0 { + z.b.abs = z.b.abs.setWord(1) + } + return z +} + +// Abs sets z to |x| (the absolute value of x) and returns z. +func (z *Rat) Abs(x *Rat) *Rat { + z.Set(x) + z.a.neg = false + return z +} + +// Neg sets z to -x and returns z. +func (z *Rat) Neg(x *Rat) *Rat { + z.Set(x) + z.a.neg = len(z.a.abs) > 0 && !z.a.neg // 0 has no sign + return z +} + +// Inv sets z to 1/x and returns z. +// If x == 0, Inv panics. +func (z *Rat) Inv(x *Rat) *Rat { + if len(x.a.abs) == 0 { + panic("division by zero") + } + z.Set(x) + z.a.abs, z.b.abs = z.b.abs, z.a.abs + return z +} + +// Sign returns: +// +// -1 if x < 0 +// 0 if x == 0 +// +1 if x > 0 +// +func (x *Rat) Sign() int { + return x.a.Sign() +} + +// IsInt reports whether the denominator of x is 1. +func (x *Rat) IsInt() bool { + return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0 +} + +// Num returns the numerator of x; it may be <= 0. +// The result is a reference to x's numerator; it +// may change if a new value is assigned to x, and vice versa. +// The sign of the numerator corresponds to the sign of x. +func (x *Rat) Num() *Int { + return &x.a +} + +// Denom returns the denominator of x; it is always > 0. +// The result is a reference to x's denominator, unless +// x is an uninitialized (zero value) Rat, in which case +// the result is a new Int of value 1. (To initialize x, +// any operation that sets x will do, including x.Set(x).) +// If the result is a reference to x's denominator it +// may change if a new value is assigned to x, and vice versa. +func (x *Rat) Denom() *Int { + // Note that x.b.neg is guaranteed false. + if len(x.b.abs) == 0 { + // Note: If this proves problematic, we could + // panic instead and require the Rat to + // be explicitly initialized. + return &Int{abs: nat{1}} + } + return &x.b +} + +func (z *Rat) norm() *Rat { + switch { + case len(z.a.abs) == 0: + // z == 0; normalize sign and denominator + z.a.neg = false + fallthrough + case len(z.b.abs) == 0: + // z is integer; normalize denominator + z.b.abs = z.b.abs.setWord(1) + default: + // z is fraction; normalize numerator and denominator + neg := z.a.neg + z.a.neg = false + z.b.neg = false + if f := NewInt(0).lehmerGCD(nil, nil, &z.a, &z.b); f.Cmp(intOne) != 0 { + z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs) + z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs) + } + z.a.neg = neg + } + return z +} + +// mulDenom sets z to the denominator product x*y (by taking into +// account that 0 values for x or y must be interpreted as 1) and +// returns z. +func mulDenom(z, x, y nat) nat { + switch { + case len(x) == 0 && len(y) == 0: + return z.setWord(1) + case len(x) == 0: + return z.set(y) + case len(y) == 0: + return z.set(x) + } + return z.mul(x, y) +} + +// scaleDenom sets z to the product x*f. +// If f == 0 (zero value of denominator), z is set to (a copy of) x. +func (z *Int) scaleDenom(x *Int, f nat) { + if len(f) == 0 { + z.Set(x) + return + } + z.abs = z.abs.mul(x.abs, f) + z.neg = x.neg +} + +// Cmp compares x and y and returns: +// +// -1 if x < y +// 0 if x == y +// +1 if x > y +// +func (x *Rat) Cmp(y *Rat) int { + var a, b Int + a.scaleDenom(&x.a, y.b.abs) + b.scaleDenom(&y.a, x.b.abs) + return a.Cmp(&b) +} + +// Add sets z to the sum x+y and returns z. +func (z *Rat) Add(x, y *Rat) *Rat { + var a1, a2 Int + a1.scaleDenom(&x.a, y.b.abs) + a2.scaleDenom(&y.a, x.b.abs) + z.a.Add(&a1, &a2) + z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs) + return z.norm() +} + +// Sub sets z to the difference x-y and returns z. +func (z *Rat) Sub(x, y *Rat) *Rat { + var a1, a2 Int + a1.scaleDenom(&x.a, y.b.abs) + a2.scaleDenom(&y.a, x.b.abs) + z.a.Sub(&a1, &a2) + z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs) + return z.norm() +} + +// Mul sets z to the product x*y and returns z. +func (z *Rat) Mul(x, y *Rat) *Rat { + if x == y { + // a squared Rat is positive and can't be reduced (no need to call norm()) + z.a.neg = false + z.a.abs = z.a.abs.sqr(x.a.abs) + if len(x.b.abs) == 0 { + z.b.abs = z.b.abs.setWord(1) + } else { + z.b.abs = z.b.abs.sqr(x.b.abs) + } + return z + } + z.a.Mul(&x.a, &y.a) + z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs) + return z.norm() +} + +// Quo sets z to the quotient x/y and returns z. +// If y == 0, Quo panics. +func (z *Rat) Quo(x, y *Rat) *Rat { + if len(y.a.abs) == 0 { + panic("division by zero") + } + var a, b Int + a.scaleDenom(&x.a, y.b.abs) + b.scaleDenom(&y.a, x.b.abs) + z.a.abs = a.abs + z.b.abs = b.abs + z.a.neg = a.neg != b.neg + return z.norm() +} diff --git a/contrib/go/_std_1.18/src/math/big/ratconv.go b/contrib/go/_std_1.18/src/math/big/ratconv.go new file mode 100644 index 0000000000..90053a9c81 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/ratconv.go @@ -0,0 +1,380 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements rat-to-string conversion functions. + +package big + +import ( + "errors" + "fmt" + "io" + "strconv" + "strings" +) + +func ratTok(ch rune) bool { + return strings.ContainsRune("+-/0123456789.eE", ch) +} + +var ratZero Rat +var _ fmt.Scanner = &ratZero // *Rat must implement fmt.Scanner + +// Scan is a support routine for fmt.Scanner. It accepts the formats +// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent. +func (z *Rat) Scan(s fmt.ScanState, ch rune) error { + tok, err := s.Token(true, ratTok) + if err != nil { + return err + } + if !strings.ContainsRune("efgEFGv", ch) { + return errors.New("Rat.Scan: invalid verb") + } + if _, ok := z.SetString(string(tok)); !ok { + return errors.New("Rat.Scan: invalid syntax") + } + return nil +} + +// SetString sets z to the value of s and returns z and a boolean indicating +// success. s can be given as a (possibly signed) fraction "a/b", or as a +// floating-point number optionally followed by an exponent. +// If a fraction is provided, both the dividend and the divisor may be a +// decimal integer or independently use a prefix of ``0b'', ``0'' or ``0o'', +// or ``0x'' (or their upper-case variants) to denote a binary, octal, or +// hexadecimal integer, respectively. The divisor may not be signed. +// If a floating-point number is provided, it may be in decimal form or +// use any of the same prefixes as above but for ``0'' to denote a non-decimal +// mantissa. A leading ``0'' is considered a decimal leading 0; it does not +// indicate octal representation in this case. +// An optional base-10 ``e'' or base-2 ``p'' (or their upper-case variants) +// exponent may be provided as well, except for hexadecimal floats which +// only accept an (optional) ``p'' exponent (because an ``e'' or ``E'' cannot +// be distinguished from a mantissa digit). If the exponent's absolute value +// is too large, the operation may fail. +// The entire string, not just a prefix, must be valid for success. If the +// operation failed, the value of z is undefined but the returned value is nil. +func (z *Rat) SetString(s string) (*Rat, bool) { + if len(s) == 0 { + return nil, false + } + // len(s) > 0 + + // parse fraction a/b, if any + if sep := strings.Index(s, "/"); sep >= 0 { + if _, ok := z.a.SetString(s[:sep], 0); !ok { + return nil, false + } + r := strings.NewReader(s[sep+1:]) + var err error + if z.b.abs, _, _, err = z.b.abs.scan(r, 0, false); err != nil { + return nil, false + } + // entire string must have been consumed + if _, err = r.ReadByte(); err != io.EOF { + return nil, false + } + if len(z.b.abs) == 0 { + return nil, false + } + return z.norm(), true + } + + // parse floating-point number + r := strings.NewReader(s) + + // sign + neg, err := scanSign(r) + if err != nil { + return nil, false + } + + // mantissa + var base int + var fcount int // fractional digit count; valid if <= 0 + z.a.abs, base, fcount, err = z.a.abs.scan(r, 0, true) + if err != nil { + return nil, false + } + + // exponent + var exp int64 + var ebase int + exp, ebase, err = scanExponent(r, true, true) + if err != nil { + return nil, false + } + + // there should be no unread characters left + if _, err = r.ReadByte(); err != io.EOF { + return nil, false + } + + // special-case 0 (see also issue #16176) + if len(z.a.abs) == 0 { + return z, true + } + // len(z.a.abs) > 0 + + // The mantissa may have a radix point (fcount <= 0) and there + // may be a nonzero exponent exp. The radix point amounts to a + // division by base**(-fcount), which equals a multiplication by + // base**fcount. An exponent means multiplication by ebase**exp. + // Multiplications are commutative, so we can apply them in any + // order. We only have powers of 2 and 10, and we split powers + // of 10 into the product of the same powers of 2 and 5. This + // may reduce the size of shift/multiplication factors or + // divisors required to create the final fraction, depending + // on the actual floating-point value. + + // determine binary or decimal exponent contribution of radix point + var exp2, exp5 int64 + if fcount < 0 { + // The mantissa has a radix point ddd.dddd; and + // -fcount is the number of digits to the right + // of '.'. Adjust relevant exponent accordingly. + d := int64(fcount) + switch base { + case 10: + exp5 = d + fallthrough // 10**e == 5**e * 2**e + case 2: + exp2 = d + case 8: + exp2 = d * 3 // octal digits are 3 bits each + case 16: + exp2 = d * 4 // hexadecimal digits are 4 bits each + default: + panic("unexpected mantissa base") + } + // fcount consumed - not needed anymore + } + + // take actual exponent into account + switch ebase { + case 10: + exp5 += exp + fallthrough // see fallthrough above + case 2: + exp2 += exp + default: + panic("unexpected exponent base") + } + // exp consumed - not needed anymore + + // apply exp5 contributions + // (start with exp5 so the numbers to multiply are smaller) + if exp5 != 0 { + n := exp5 + if n < 0 { + n = -n + if n < 0 { + // This can occur if -n overflows. -(-1 << 63) would become + // -1 << 63, which is still negative. + return nil, false + } + } + if n > 1e6 { + return nil, false // avoid excessively large exponents + } + pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs + if exp5 > 0 { + z.a.abs = z.a.abs.mul(z.a.abs, pow5) + z.b.abs = z.b.abs.setWord(1) + } else { + z.b.abs = pow5 + } + } else { + z.b.abs = z.b.abs.setWord(1) + } + + // apply exp2 contributions + if exp2 < -1e7 || exp2 > 1e7 { + return nil, false // avoid excessively large exponents + } + if exp2 > 0 { + z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2)) + } else if exp2 < 0 { + z.b.abs = z.b.abs.shl(z.b.abs, uint(-exp2)) + } + + z.a.neg = neg && len(z.a.abs) > 0 // 0 has no sign + + return z.norm(), true +} + +// scanExponent scans the longest possible prefix of r representing a base 10 +// (``e'', ``E'') or a base 2 (``p'', ``P'') exponent, if any. It returns the +// exponent, the exponent base (10 or 2), or a read or syntax error, if any. +// +// If sepOk is set, an underscore character ``_'' may appear between successive +// exponent digits; such underscores do not change the value of the exponent. +// Incorrect placement of underscores is reported as an error if there are no +// other errors. If sepOk is not set, underscores are not recognized and thus +// terminate scanning like any other character that is not a valid digit. +// +// exponent = ( "e" | "E" | "p" | "P" ) [ sign ] digits . +// sign = "+" | "-" . +// digits = digit { [ '_' ] digit } . +// digit = "0" ... "9" . +// +// A base 2 exponent is only permitted if base2ok is set. +func scanExponent(r io.ByteScanner, base2ok, sepOk bool) (exp int64, base int, err error) { + // one char look-ahead + ch, err := r.ReadByte() + if err != nil { + if err == io.EOF { + err = nil + } + return 0, 10, err + } + + // exponent char + switch ch { + case 'e', 'E': + base = 10 + case 'p', 'P': + if base2ok { + base = 2 + break // ok + } + fallthrough // binary exponent not permitted + default: + r.UnreadByte() // ch does not belong to exponent anymore + return 0, 10, nil + } + + // sign + var digits []byte + ch, err = r.ReadByte() + if err == nil && (ch == '+' || ch == '-') { + if ch == '-' { + digits = append(digits, '-') + } + ch, err = r.ReadByte() + } + + // prev encodes the previously seen char: it is one + // of '_', '0' (a digit), or '.' (anything else). A + // valid separator '_' may only occur after a digit. + prev := '.' + invalSep := false + + // exponent value + hasDigits := false + for err == nil { + if '0' <= ch && ch <= '9' { + digits = append(digits, ch) + prev = '0' + hasDigits = true + } else if ch == '_' && sepOk { + if prev != '0' { + invalSep = true + } + prev = '_' + } else { + r.UnreadByte() // ch does not belong to number anymore + break + } + ch, err = r.ReadByte() + } + + if err == io.EOF { + err = nil + } + if err == nil && !hasDigits { + err = errNoDigits + } + if err == nil { + exp, err = strconv.ParseInt(string(digits), 10, 64) + } + // other errors take precedence over invalid separators + if err == nil && (invalSep || prev == '_') { + err = errInvalSep + } + + return +} + +// String returns a string representation of x in the form "a/b" (even if b == 1). +func (x *Rat) String() string { + return string(x.marshal()) +} + +// marshal implements String returning a slice of bytes +func (x *Rat) marshal() []byte { + var buf []byte + buf = x.a.Append(buf, 10) + buf = append(buf, '/') + if len(x.b.abs) != 0 { + buf = x.b.Append(buf, 10) + } else { + buf = append(buf, '1') + } + return buf +} + +// RatString returns a string representation of x in the form "a/b" if b != 1, +// and in the form "a" if b == 1. +func (x *Rat) RatString() string { + if x.IsInt() { + return x.a.String() + } + return x.String() +} + +// FloatString returns a string representation of x in decimal form with prec +// digits of precision after the radix point. The last digit is rounded to +// nearest, with halves rounded away from zero. +func (x *Rat) FloatString(prec int) string { + var buf []byte + + if x.IsInt() { + buf = x.a.Append(buf, 10) + if prec > 0 { + buf = append(buf, '.') + for i := prec; i > 0; i-- { + buf = append(buf, '0') + } + } + return string(buf) + } + // x.b.abs != 0 + + q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs) + + p := natOne + if prec > 0 { + p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil) + } + + r = r.mul(r, p) + r, r2 := r.div(nat(nil), r, x.b.abs) + + // see if we need to round up + r2 = r2.add(r2, r2) + if x.b.abs.cmp(r2) <= 0 { + r = r.add(r, natOne) + if r.cmp(p) >= 0 { + q = nat(nil).add(q, natOne) + r = nat(nil).sub(r, p) + } + } + + if x.a.neg { + buf = append(buf, '-') + } + buf = append(buf, q.utoa(10)...) // itoa ignores sign if q == 0 + + if prec > 0 { + buf = append(buf, '.') + rs := r.utoa(10) + for i := prec - len(rs); i > 0; i-- { + buf = append(buf, '0') + } + buf = append(buf, rs...) + } + + return string(buf) +} diff --git a/contrib/go/_std_1.18/src/math/big/ratmarsh.go b/contrib/go/_std_1.18/src/math/big/ratmarsh.go new file mode 100644 index 0000000000..fbc7b6002d --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/ratmarsh.go @@ -0,0 +1,75 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements encoding/decoding of Rats. + +package big + +import ( + "encoding/binary" + "errors" + "fmt" +) + +// Gob codec version. Permits backward-compatible changes to the encoding. +const ratGobVersion byte = 1 + +// GobEncode implements the gob.GobEncoder interface. +func (x *Rat) GobEncode() ([]byte, error) { + if x == nil { + return nil, nil + } + buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4) + i := x.b.abs.bytes(buf) + j := x.a.abs.bytes(buf[:i]) + n := i - j + if int(uint32(n)) != n { + // this should never happen + return nil, errors.New("Rat.GobEncode: numerator too large") + } + binary.BigEndian.PutUint32(buf[j-4:j], uint32(n)) + j -= 1 + 4 + b := ratGobVersion << 1 // make space for sign bit + if x.a.neg { + b |= 1 + } + buf[j] = b + return buf[j:], nil +} + +// GobDecode implements the gob.GobDecoder interface. +func (z *Rat) GobDecode(buf []byte) error { + if len(buf) == 0 { + // Other side sent a nil or default value. + *z = Rat{} + return nil + } + b := buf[0] + if b>>1 != ratGobVersion { + return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1) + } + const j = 1 + 4 + i := j + binary.BigEndian.Uint32(buf[j-4:j]) + z.a.neg = b&1 != 0 + z.a.abs = z.a.abs.setBytes(buf[j:i]) + z.b.abs = z.b.abs.setBytes(buf[i:]) + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (x *Rat) MarshalText() (text []byte, err error) { + if x.IsInt() { + return x.a.MarshalText() + } + return x.marshal(), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (z *Rat) UnmarshalText(text []byte) error { + // TODO(gri): get rid of the []byte/string conversion + if _, ok := z.SetString(string(text)); !ok { + return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text) + } + return nil +} diff --git a/contrib/go/_std_1.18/src/math/big/roundingmode_string.go b/contrib/go/_std_1.18/src/math/big/roundingmode_string.go new file mode 100644 index 0000000000..c7629eb98b --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/roundingmode_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=RoundingMode"; DO NOT EDIT. + +package big + +import "strconv" + +const _RoundingMode_name = "ToNearestEvenToNearestAwayToZeroAwayFromZeroToNegativeInfToPositiveInf" + +var _RoundingMode_index = [...]uint8{0, 13, 26, 32, 44, 57, 70} + +func (i RoundingMode) String() string { + if i >= RoundingMode(len(_RoundingMode_index)-1) { + return "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]] +} diff --git a/contrib/go/_std_1.18/src/math/big/sqrt.go b/contrib/go/_std_1.18/src/math/big/sqrt.go new file mode 100644 index 0000000000..0d50164557 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/big/sqrt.go @@ -0,0 +1,128 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package big + +import ( + "math" + "sync" +) + +var threeOnce struct { + sync.Once + v *Float +} + +func three() *Float { + threeOnce.Do(func() { + threeOnce.v = NewFloat(3.0) + }) + return threeOnce.v +} + +// Sqrt sets z to the rounded square root of x, and returns it. +// +// If z's precision is 0, it is changed to x's precision before the +// operation. Rounding is performed according to z's precision and +// rounding mode, but z's accuracy is not computed. Specifically, the +// result of z.Acc() is undefined. +// +// The function panics if z < 0. The value of z is undefined in that +// case. +func (z *Float) Sqrt(x *Float) *Float { + if debugFloat { + x.validate() + } + + if z.prec == 0 { + z.prec = x.prec + } + + if x.Sign() == -1 { + // following IEEE754-2008 (section 7.2) + panic(ErrNaN{"square root of negative operand"}) + } + + // handle ±0 and +∞ + if x.form != finite { + z.acc = Exact + z.form = x.form + z.neg = x.neg // IEEE754-2008 requires √±0 = ±0 + return z + } + + // MantExp sets the argument's precision to the receiver's, and + // when z.prec > x.prec this will lower z.prec. Restore it after + // the MantExp call. + prec := z.prec + b := x.MantExp(z) + z.prec = prec + + // Compute √(z·2**b) as + // √( z)·2**(½b) if b is even + // √(2z)·2**(⌊½b⌋) if b > 0 is odd + // √(½z)·2**(⌈½b⌉) if b < 0 is odd + switch b % 2 { + case 0: + // nothing to do + case 1: + z.exp++ + case -1: + z.exp-- + } + // 0.25 <= z < 2.0 + + // Solving 1/x² - z = 0 avoids Quo calls and is faster, especially + // for high precisions. + z.sqrtInverse(z) + + // re-attach halved exponent + return z.SetMantExp(z, b/2) +} + +// Compute √x (to z.prec precision) by solving +// 1/t² - x = 0 +// for t (using Newton's method), and then inverting. +func (z *Float) sqrtInverse(x *Float) { + // let + // f(t) = 1/t² - x + // then + // g(t) = f(t)/f'(t) = -½t(1 - xt²) + // and the next guess is given by + // t2 = t - g(t) = ½t(3 - xt²) + u := newFloat(z.prec) + v := newFloat(z.prec) + three := three() + ng := func(t *Float) *Float { + u.prec = t.prec + v.prec = t.prec + u.Mul(t, t) // u = t² + u.Mul(x, u) // = xt² + v.Sub(three, u) // v = 3 - xt² + u.Mul(t, v) // u = t(3 - xt²) + u.exp-- // = ½t(3 - xt²) + return t.Set(u) + } + + xf, _ := x.Float64() + sqi := newFloat(z.prec) + sqi.SetFloat64(1 / math.Sqrt(xf)) + for prec := z.prec + 32; sqi.prec < prec; { + sqi.prec *= 2 + sqi = ng(sqi) + } + // sqi = 1/√x + + // x/√x = √x + z.Mul(x, sqi) +} + +// newFloat returns a new *Float with space for twice the given +// precision. +func newFloat(prec2 uint32) *Float { + z := new(Float) + // nat.make ensures the slice length is > 0 + z.mant = z.mant.make(int(prec2/_W) * 2) + return z +} diff --git a/contrib/go/_std_1.18/src/math/bits.go b/contrib/go/_std_1.18/src/math/bits.go new file mode 100644 index 0000000000..77bcdbe1ce --- /dev/null +++ b/contrib/go/_std_1.18/src/math/bits.go @@ -0,0 +1,62 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +const ( + uvnan = 0x7FF8000000000001 + uvinf = 0x7FF0000000000000 + uvneginf = 0xFFF0000000000000 + uvone = 0x3FF0000000000000 + mask = 0x7FF + shift = 64 - 11 - 1 + bias = 1023 + signMask = 1 << 63 + fracMask = 1<<shift - 1 +) + +// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0. +func Inf(sign int) float64 { + var v uint64 + if sign >= 0 { + v = uvinf + } else { + v = uvneginf + } + return Float64frombits(v) +} + +// NaN returns an IEEE 754 ``not-a-number'' value. +func NaN() float64 { return Float64frombits(uvnan) } + +// IsNaN reports whether f is an IEEE 754 ``not-a-number'' value. +func IsNaN(f float64) (is bool) { + // IEEE 754 says that only NaNs satisfy f != f. + // To avoid the floating-point hardware, could use: + // x := Float64bits(f); + // return uint32(x>>shift)&mask == mask && x != uvinf && x != uvneginf + return f != f +} + +// IsInf reports whether f is an infinity, according to sign. +// If sign > 0, IsInf reports whether f is positive infinity. +// If sign < 0, IsInf reports whether f is negative infinity. +// If sign == 0, IsInf reports whether f is either infinity. +func IsInf(f float64, sign int) bool { + // Test for infinity by comparing against maximum float. + // To avoid the floating-point hardware, could use: + // x := Float64bits(f); + // return sign >= 0 && x == uvinf || sign <= 0 && x == uvneginf; + return sign >= 0 && f > MaxFloat64 || sign <= 0 && f < -MaxFloat64 +} + +// normalize returns a normal number y and exponent exp +// satisfying x == y × 2**exp. It assumes x is finite and non-zero. +func normalize(x float64) (y float64, exp int) { + const SmallestNormal = 2.2250738585072014e-308 // 2**-1022 + if Abs(x) < SmallestNormal { + return x * (1 << 52), -52 + } + return x, 0 +} diff --git a/contrib/go/_std_1.18/src/math/bits/bits.go b/contrib/go/_std_1.18/src/math/bits/bits.go new file mode 100644 index 0000000000..65452feda2 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/bits/bits.go @@ -0,0 +1,588 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run make_tables.go + +// Package bits implements bit counting and manipulation +// functions for the predeclared unsigned integer types. +package bits + +const uintSize = 32 << (^uint(0) >> 63) // 32 or 64 + +// UintSize is the size of a uint in bits. +const UintSize = uintSize + +// --- LeadingZeros --- + +// LeadingZeros returns the number of leading zero bits in x; the result is UintSize for x == 0. +func LeadingZeros(x uint) int { return UintSize - Len(x) } + +// LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0. +func LeadingZeros8(x uint8) int { return 8 - Len8(x) } + +// LeadingZeros16 returns the number of leading zero bits in x; the result is 16 for x == 0. +func LeadingZeros16(x uint16) int { return 16 - Len16(x) } + +// LeadingZeros32 returns the number of leading zero bits in x; the result is 32 for x == 0. +func LeadingZeros32(x uint32) int { return 32 - Len32(x) } + +// LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0. +func LeadingZeros64(x uint64) int { return 64 - Len64(x) } + +// --- TrailingZeros --- + +// See http://supertech.csail.mit.edu/papers/debruijn.pdf +const deBruijn32 = 0x077CB531 + +var deBruijn32tab = [32]byte{ + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9, +} + +const deBruijn64 = 0x03f79d71b4ca8b09 + +var deBruijn64tab = [64]byte{ + 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, + 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, + 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11, + 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6, +} + +// TrailingZeros returns the number of trailing zero bits in x; the result is UintSize for x == 0. +func TrailingZeros(x uint) int { + if UintSize == 32 { + return TrailingZeros32(uint32(x)) + } + return TrailingZeros64(uint64(x)) +} + +// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0. +func TrailingZeros8(x uint8) int { + return int(ntz8tab[x]) +} + +// TrailingZeros16 returns the number of trailing zero bits in x; the result is 16 for x == 0. +func TrailingZeros16(x uint16) int { + if x == 0 { + return 16 + } + // see comment in TrailingZeros64 + return int(deBruijn32tab[uint32(x&-x)*deBruijn32>>(32-5)]) +} + +// TrailingZeros32 returns the number of trailing zero bits in x; the result is 32 for x == 0. +func TrailingZeros32(x uint32) int { + if x == 0 { + return 32 + } + // see comment in TrailingZeros64 + return int(deBruijn32tab[(x&-x)*deBruijn32>>(32-5)]) +} + +// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0. +func TrailingZeros64(x uint64) int { + if x == 0 { + return 64 + } + // If popcount is fast, replace code below with return popcount(^x & (x - 1)). + // + // x & -x leaves only the right-most bit set in the word. Let k be the + // index of that bit. Since only a single bit is set, the value is two + // to the power of k. Multiplying by a power of two is equivalent to + // left shifting, in this case by k bits. The de Bruijn (64 bit) constant + // is such that all six bit, consecutive substrings are distinct. + // Therefore, if we have a left shifted version of this constant we can + // find by how many bits it was shifted by looking at which six bit + // substring ended up at the top of the word. + // (Knuth, volume 4, section 7.3.1) + return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)]) +} + +// --- OnesCount --- + +const m0 = 0x5555555555555555 // 01010101 ... +const m1 = 0x3333333333333333 // 00110011 ... +const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ... +const m3 = 0x00ff00ff00ff00ff // etc. +const m4 = 0x0000ffff0000ffff + +// OnesCount returns the number of one bits ("population count") in x. +func OnesCount(x uint) int { + if UintSize == 32 { + return OnesCount32(uint32(x)) + } + return OnesCount64(uint64(x)) +} + +// OnesCount8 returns the number of one bits ("population count") in x. +func OnesCount8(x uint8) int { + return int(pop8tab[x]) +} + +// OnesCount16 returns the number of one bits ("population count") in x. +func OnesCount16(x uint16) int { + return int(pop8tab[x>>8] + pop8tab[x&0xff]) +} + +// OnesCount32 returns the number of one bits ("population count") in x. +func OnesCount32(x uint32) int { + return int(pop8tab[x>>24] + pop8tab[x>>16&0xff] + pop8tab[x>>8&0xff] + pop8tab[x&0xff]) +} + +// OnesCount64 returns the number of one bits ("population count") in x. +func OnesCount64(x uint64) int { + // Implementation: Parallel summing of adjacent bits. + // See "Hacker's Delight", Chap. 5: Counting Bits. + // The following pattern shows the general approach: + // + // x = x>>1&(m0&m) + x&(m0&m) + // x = x>>2&(m1&m) + x&(m1&m) + // x = x>>4&(m2&m) + x&(m2&m) + // x = x>>8&(m3&m) + x&(m3&m) + // x = x>>16&(m4&m) + x&(m4&m) + // x = x>>32&(m5&m) + x&(m5&m) + // return int(x) + // + // Masking (& operations) can be left away when there's no + // danger that a field's sum will carry over into the next + // field: Since the result cannot be > 64, 8 bits is enough + // and we can ignore the masks for the shifts by 8 and up. + // Per "Hacker's Delight", the first line can be simplified + // more, but it saves at best one instruction, so we leave + // it alone for clarity. + const m = 1<<64 - 1 + x = x>>1&(m0&m) + x&(m0&m) + x = x>>2&(m1&m) + x&(m1&m) + x = (x>>4 + x) & (m2 & m) + x += x >> 8 + x += x >> 16 + x += x >> 32 + return int(x) & (1<<7 - 1) +} + +// --- RotateLeft --- + +// RotateLeft returns the value of x rotated left by (k mod UintSize) bits. +// To rotate x right by k bits, call RotateLeft(x, -k). +// +// This function's execution time does not depend on the inputs. +func RotateLeft(x uint, k int) uint { + if UintSize == 32 { + return uint(RotateLeft32(uint32(x), k)) + } + return uint(RotateLeft64(uint64(x), k)) +} + +// RotateLeft8 returns the value of x rotated left by (k mod 8) bits. +// To rotate x right by k bits, call RotateLeft8(x, -k). +// +// This function's execution time does not depend on the inputs. +func RotateLeft8(x uint8, k int) uint8 { + const n = 8 + s := uint(k) & (n - 1) + return x<<s | x>>(n-s) +} + +// RotateLeft16 returns the value of x rotated left by (k mod 16) bits. +// To rotate x right by k bits, call RotateLeft16(x, -k). +// +// This function's execution time does not depend on the inputs. +func RotateLeft16(x uint16, k int) uint16 { + const n = 16 + s := uint(k) & (n - 1) + return x<<s | x>>(n-s) +} + +// RotateLeft32 returns the value of x rotated left by (k mod 32) bits. +// To rotate x right by k bits, call RotateLeft32(x, -k). +// +// This function's execution time does not depend on the inputs. +func RotateLeft32(x uint32, k int) uint32 { + const n = 32 + s := uint(k) & (n - 1) + return x<<s | x>>(n-s) +} + +// RotateLeft64 returns the value of x rotated left by (k mod 64) bits. +// To rotate x right by k bits, call RotateLeft64(x, -k). +// +// This function's execution time does not depend on the inputs. +func RotateLeft64(x uint64, k int) uint64 { + const n = 64 + s := uint(k) & (n - 1) + return x<<s | x>>(n-s) +} + +// --- Reverse --- + +// Reverse returns the value of x with its bits in reversed order. +func Reverse(x uint) uint { + if UintSize == 32 { + return uint(Reverse32(uint32(x))) + } + return uint(Reverse64(uint64(x))) +} + +// Reverse8 returns the value of x with its bits in reversed order. +func Reverse8(x uint8) uint8 { + return rev8tab[x] +} + +// Reverse16 returns the value of x with its bits in reversed order. +func Reverse16(x uint16) uint16 { + return uint16(rev8tab[x>>8]) | uint16(rev8tab[x&0xff])<<8 +} + +// Reverse32 returns the value of x with its bits in reversed order. +func Reverse32(x uint32) uint32 { + const m = 1<<32 - 1 + x = x>>1&(m0&m) | x&(m0&m)<<1 + x = x>>2&(m1&m) | x&(m1&m)<<2 + x = x>>4&(m2&m) | x&(m2&m)<<4 + return ReverseBytes32(x) +} + +// Reverse64 returns the value of x with its bits in reversed order. +func Reverse64(x uint64) uint64 { + const m = 1<<64 - 1 + x = x>>1&(m0&m) | x&(m0&m)<<1 + x = x>>2&(m1&m) | x&(m1&m)<<2 + x = x>>4&(m2&m) | x&(m2&m)<<4 + return ReverseBytes64(x) +} + +// --- ReverseBytes --- + +// ReverseBytes returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. +func ReverseBytes(x uint) uint { + if UintSize == 32 { + return uint(ReverseBytes32(uint32(x))) + } + return uint(ReverseBytes64(uint64(x))) +} + +// ReverseBytes16 returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. +func ReverseBytes16(x uint16) uint16 { + return x>>8 | x<<8 +} + +// ReverseBytes32 returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. +func ReverseBytes32(x uint32) uint32 { + const m = 1<<32 - 1 + x = x>>8&(m3&m) | x&(m3&m)<<8 + return x>>16 | x<<16 +} + +// ReverseBytes64 returns the value of x with its bytes in reversed order. +// +// This function's execution time does not depend on the inputs. +func ReverseBytes64(x uint64) uint64 { + const m = 1<<64 - 1 + x = x>>8&(m3&m) | x&(m3&m)<<8 + x = x>>16&(m4&m) | x&(m4&m)<<16 + return x>>32 | x<<32 +} + +// --- Len --- + +// Len returns the minimum number of bits required to represent x; the result is 0 for x == 0. +func Len(x uint) int { + if UintSize == 32 { + return Len32(uint32(x)) + } + return Len64(uint64(x)) +} + +// Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +func Len8(x uint8) int { + return int(len8tab[x]) +} + +// Len16 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +func Len16(x uint16) (n int) { + if x >= 1<<8 { + x >>= 8 + n = 8 + } + return n + int(len8tab[x]) +} + +// Len32 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +func Len32(x uint32) (n int) { + if x >= 1<<16 { + x >>= 16 + n = 16 + } + if x >= 1<<8 { + x >>= 8 + n += 8 + } + return n + int(len8tab[x]) +} + +// Len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +func Len64(x uint64) (n int) { + if x >= 1<<32 { + x >>= 32 + n = 32 + } + if x >= 1<<16 { + x >>= 16 + n += 16 + } + if x >= 1<<8 { + x >>= 8 + n += 8 + } + return n + int(len8tab[x]) +} + +// --- Add with carry --- + +// Add returns the sum with carry of x, y and carry: sum = x + y + carry. +// The carry input must be 0 or 1; otherwise the behavior is undefined. +// The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Add(x, y, carry uint) (sum, carryOut uint) { + if UintSize == 32 { + s32, c32 := Add32(uint32(x), uint32(y), uint32(carry)) + return uint(s32), uint(c32) + } + s64, c64 := Add64(uint64(x), uint64(y), uint64(carry)) + return uint(s64), uint(c64) +} + +// Add32 returns the sum with carry of x, y and carry: sum = x + y + carry. +// The carry input must be 0 or 1; otherwise the behavior is undefined. +// The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Add32(x, y, carry uint32) (sum, carryOut uint32) { + sum64 := uint64(x) + uint64(y) + uint64(carry) + sum = uint32(sum64) + carryOut = uint32(sum64 >> 32) + return +} + +// Add64 returns the sum with carry of x, y and carry: sum = x + y + carry. +// The carry input must be 0 or 1; otherwise the behavior is undefined. +// The carryOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Add64(x, y, carry uint64) (sum, carryOut uint64) { + sum = x + y + carry + // The sum will overflow if both top bits are set (x & y) or if one of them + // is (x | y), and a carry from the lower place happened. If such a carry + // happens, the top bit will be 1 + 0 + 1 = 0 (&^ sum). + carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 + return +} + +// --- Subtract with borrow --- + +// Sub returns the difference of x, y and borrow: diff = x - y - borrow. +// The borrow input must be 0 or 1; otherwise the behavior is undefined. +// The borrowOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Sub(x, y, borrow uint) (diff, borrowOut uint) { + if UintSize == 32 { + d32, b32 := Sub32(uint32(x), uint32(y), uint32(borrow)) + return uint(d32), uint(b32) + } + d64, b64 := Sub64(uint64(x), uint64(y), uint64(borrow)) + return uint(d64), uint(b64) +} + +// Sub32 returns the difference of x, y and borrow, diff = x - y - borrow. +// The borrow input must be 0 or 1; otherwise the behavior is undefined. +// The borrowOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Sub32(x, y, borrow uint32) (diff, borrowOut uint32) { + diff = x - y - borrow + // The difference will underflow if the top bit of x is not set and the top + // bit of y is set (^x & y) or if they are the same (^(x ^ y)) and a borrow + // from the lower place happens. If that borrow happens, the result will be + // 1 - 1 - 1 = 0 - 0 - 1 = 1 (& diff). + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 31 + return +} + +// Sub64 returns the difference of x, y and borrow: diff = x - y - borrow. +// The borrow input must be 0 or 1; otherwise the behavior is undefined. +// The borrowOut output is guaranteed to be 0 or 1. +// +// This function's execution time does not depend on the inputs. +func Sub64(x, y, borrow uint64) (diff, borrowOut uint64) { + diff = x - y - borrow + // See Sub32 for the bit logic. + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 + return +} + +// --- Full-width multiply --- + +// Mul returns the full-width product of x and y: (hi, lo) = x * y +// with the product bits' upper half returned in hi and the lower +// half returned in lo. +// +// This function's execution time does not depend on the inputs. +func Mul(x, y uint) (hi, lo uint) { + if UintSize == 32 { + h, l := Mul32(uint32(x), uint32(y)) + return uint(h), uint(l) + } + h, l := Mul64(uint64(x), uint64(y)) + return uint(h), uint(l) +} + +// Mul32 returns the 64-bit product of x and y: (hi, lo) = x * y +// with the product bits' upper half returned in hi and the lower +// half returned in lo. +// +// This function's execution time does not depend on the inputs. +func Mul32(x, y uint32) (hi, lo uint32) { + tmp := uint64(x) * uint64(y) + hi, lo = uint32(tmp>>32), uint32(tmp) + return +} + +// Mul64 returns the 128-bit product of x and y: (hi, lo) = x * y +// with the product bits' upper half returned in hi and the lower +// half returned in lo. +// +// This function's execution time does not depend on the inputs. +func Mul64(x, y uint64) (hi, lo uint64) { + const mask32 = 1<<32 - 1 + x0 := x & mask32 + x1 := x >> 32 + y0 := y & mask32 + y1 := y >> 32 + w0 := x0 * y0 + t := x1*y0 + w0>>32 + w1 := t & mask32 + w2 := t >> 32 + w1 += x0 * y1 + hi = x1*y1 + w2 + w1>>32 + lo = x * y + return +} + +// --- Full-width divide --- + +// Div returns the quotient and remainder of (hi, lo) divided by y: +// quo = (hi, lo)/y, rem = (hi, lo)%y with the dividend bits' upper +// half in parameter hi and the lower half in parameter lo. +// Div panics for y == 0 (division by zero) or y <= hi (quotient overflow). +func Div(hi, lo, y uint) (quo, rem uint) { + if UintSize == 32 { + q, r := Div32(uint32(hi), uint32(lo), uint32(y)) + return uint(q), uint(r) + } + q, r := Div64(uint64(hi), uint64(lo), uint64(y)) + return uint(q), uint(r) +} + +// Div32 returns the quotient and remainder of (hi, lo) divided by y: +// quo = (hi, lo)/y, rem = (hi, lo)%y with the dividend bits' upper +// half in parameter hi and the lower half in parameter lo. +// Div32 panics for y == 0 (division by zero) or y <= hi (quotient overflow). +func Div32(hi, lo, y uint32) (quo, rem uint32) { + if y != 0 && y <= hi { + panic(overflowError) + } + z := uint64(hi)<<32 | uint64(lo) + quo, rem = uint32(z/uint64(y)), uint32(z%uint64(y)) + return +} + +// Div64 returns the quotient and remainder of (hi, lo) divided by y: +// quo = (hi, lo)/y, rem = (hi, lo)%y with the dividend bits' upper +// half in parameter hi and the lower half in parameter lo. +// Div64 panics for y == 0 (division by zero) or y <= hi (quotient overflow). +func Div64(hi, lo, y uint64) (quo, rem uint64) { + const ( + two32 = 1 << 32 + mask32 = two32 - 1 + ) + if y == 0 { + panic(divideError) + } + if y <= hi { + panic(overflowError) + } + + s := uint(LeadingZeros64(y)) + y <<= s + + yn1 := y >> 32 + yn0 := y & mask32 + un32 := hi<<s | lo>>(64-s) + un10 := lo << s + un1 := un10 >> 32 + un0 := un10 & mask32 + q1 := un32 / yn1 + rhat := un32 - q1*yn1 + + for q1 >= two32 || q1*yn0 > two32*rhat+un1 { + q1-- + rhat += yn1 + if rhat >= two32 { + break + } + } + + un21 := un32*two32 + un1 - q1*y + q0 := un21 / yn1 + rhat = un21 - q0*yn1 + + for q0 >= two32 || q0*yn0 > two32*rhat+un0 { + q0-- + rhat += yn1 + if rhat >= two32 { + break + } + } + + return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s +} + +// Rem returns the remainder of (hi, lo) divided by y. Rem panics for +// y == 0 (division by zero) but, unlike Div, it doesn't panic on a +// quotient overflow. +func Rem(hi, lo, y uint) uint { + if UintSize == 32 { + return uint(Rem32(uint32(hi), uint32(lo), uint32(y))) + } + return uint(Rem64(uint64(hi), uint64(lo), uint64(y))) +} + +// Rem32 returns the remainder of (hi, lo) divided by y. Rem32 panics +// for y == 0 (division by zero) but, unlike Div32, it doesn't panic +// on a quotient overflow. +func Rem32(hi, lo, y uint32) uint32 { + return uint32((uint64(hi)<<32 | uint64(lo)) % uint64(y)) +} + +// Rem64 returns the remainder of (hi, lo) divided by y. Rem64 panics +// for y == 0 (division by zero) but, unlike Div64, it doesn't panic +// on a quotient overflow. +func Rem64(hi, lo, y uint64) uint64 { + // We scale down hi so that hi < y, then use Div64 to compute the + // rem with the guarantee that it won't panic on quotient overflow. + // Given that + // hi ≡ hi%y (mod y) + // we have + // hi<<64 + lo ≡ (hi%y)<<64 + lo (mod y) + _, rem := Div64(hi%y, lo, y) + return rem +} diff --git a/contrib/go/_std_1.18/src/math/bits/bits_errors.go b/contrib/go/_std_1.18/src/math/bits/bits_errors.go new file mode 100644 index 0000000000..61cb5c9457 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/bits/bits_errors.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !compiler_bootstrap +// +build !compiler_bootstrap + +package bits + +import _ "unsafe" + +//go:linkname overflowError runtime.overflowError +var overflowError error + +//go:linkname divideError runtime.divideError +var divideError error diff --git a/contrib/go/_std_1.18/src/math/bits/bits_tables.go b/contrib/go/_std_1.18/src/math/bits/bits_tables.go new file mode 100644 index 0000000000..f869b8d5c3 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/bits/bits_tables.go @@ -0,0 +1,79 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by go run make_tables.go. DO NOT EDIT. + +package bits + +const ntz8tab = "" + + "\x08\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x07\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + + "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" + +const pop8tab = "" + + "\x00\x01\x01\x02\x01\x02\x02\x03\x01\x02\x02\x03\x02\x03\x03\x04" + + "\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" + + "\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" + + "\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" + + "\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" + + "\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" + + "\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" + + "\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" + + "\x01\x02\x02\x03\x02\x03\x03\x04\x02\x03\x03\x04\x03\x04\x04\x05" + + "\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" + + "\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" + + "\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" + + "\x02\x03\x03\x04\x03\x04\x04\x05\x03\x04\x04\x05\x04\x05\x05\x06" + + "\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" + + "\x03\x04\x04\x05\x04\x05\x05\x06\x04\x05\x05\x06\x05\x06\x06\x07" + + "\x04\x05\x05\x06\x05\x06\x06\x07\x05\x06\x06\x07\x06\x07\x07\x08" + +const rev8tab = "" + + "\x00\x80\x40\xc0\x20\xa0\x60\xe0\x10\x90\x50\xd0\x30\xb0\x70\xf0" + + "\x08\x88\x48\xc8\x28\xa8\x68\xe8\x18\x98\x58\xd8\x38\xb8\x78\xf8" + + "\x04\x84\x44\xc4\x24\xa4\x64\xe4\x14\x94\x54\xd4\x34\xb4\x74\xf4" + + "\x0c\x8c\x4c\xcc\x2c\xac\x6c\xec\x1c\x9c\x5c\xdc\x3c\xbc\x7c\xfc" + + "\x02\x82\x42\xc2\x22\xa2\x62\xe2\x12\x92\x52\xd2\x32\xb2\x72\xf2" + + "\x0a\x8a\x4a\xca\x2a\xaa\x6a\xea\x1a\x9a\x5a\xda\x3a\xba\x7a\xfa" + + "\x06\x86\x46\xc6\x26\xa6\x66\xe6\x16\x96\x56\xd6\x36\xb6\x76\xf6" + + "\x0e\x8e\x4e\xce\x2e\xae\x6e\xee\x1e\x9e\x5e\xde\x3e\xbe\x7e\xfe" + + "\x01\x81\x41\xc1\x21\xa1\x61\xe1\x11\x91\x51\xd1\x31\xb1\x71\xf1" + + "\x09\x89\x49\xc9\x29\xa9\x69\xe9\x19\x99\x59\xd9\x39\xb9\x79\xf9" + + "\x05\x85\x45\xc5\x25\xa5\x65\xe5\x15\x95\x55\xd5\x35\xb5\x75\xf5" + + "\x0d\x8d\x4d\xcd\x2d\xad\x6d\xed\x1d\x9d\x5d\xdd\x3d\xbd\x7d\xfd" + + "\x03\x83\x43\xc3\x23\xa3\x63\xe3\x13\x93\x53\xd3\x33\xb3\x73\xf3" + + "\x0b\x8b\x4b\xcb\x2b\xab\x6b\xeb\x1b\x9b\x5b\xdb\x3b\xbb\x7b\xfb" + + "\x07\x87\x47\xc7\x27\xa7\x67\xe7\x17\x97\x57\xd7\x37\xb7\x77\xf7" + + "\x0f\x8f\x4f\xcf\x2f\xaf\x6f\xef\x1f\x9f\x5f\xdf\x3f\xbf\x7f\xff" + +const len8tab = "" + + "\x00\x01\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04\x04\x04" + + "\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05" + + "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" + + "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" + + "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + + "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + + "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + + "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" + + "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" diff --git a/contrib/go/_std_1.18/src/math/cbrt.go b/contrib/go/_std_1.18/src/math/cbrt.go new file mode 100644 index 0000000000..45c8ecb3a8 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/cbrt.go @@ -0,0 +1,84 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The go code is a modified version of the original C code from +// http://www.netlib.org/fdlibm/s_cbrt.c and came with this notice. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunSoft, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== + +// Cbrt returns the cube root of x. +// +// Special cases are: +// Cbrt(±0) = ±0 +// Cbrt(±Inf) = ±Inf +// Cbrt(NaN) = NaN +func Cbrt(x float64) float64 { + if haveArchCbrt { + return archCbrt(x) + } + return cbrt(x) +} + +func cbrt(x float64) float64 { + const ( + B1 = 715094163 // (682-0.03306235651)*2**20 + B2 = 696219795 // (664-0.03306235651)*2**20 + C = 5.42857142857142815906e-01 // 19/35 = 0x3FE15F15F15F15F1 + D = -7.05306122448979611050e-01 // -864/1225 = 0xBFE691DE2532C834 + E = 1.41428571428571436819e+00 // 99/70 = 0x3FF6A0EA0EA0EA0F + F = 1.60714285714285720630e+00 // 45/28 = 0x3FF9B6DB6DB6DB6E + G = 3.57142857142857150787e-01 // 5/14 = 0x3FD6DB6DB6DB6DB7 + SmallestNormal = 2.22507385850720138309e-308 // 2**-1022 = 0x0010000000000000 + ) + // special cases + switch { + case x == 0 || IsNaN(x) || IsInf(x, 0): + return x + } + + sign := false + if x < 0 { + x = -x + sign = true + } + + // rough cbrt to 5 bits + t := Float64frombits(Float64bits(x)/3 + B1<<32) + if x < SmallestNormal { + // subnormal number + t = float64(1 << 54) // set t= 2**54 + t *= x + t = Float64frombits(Float64bits(t)/3 + B2<<32) + } + + // new cbrt to 23 bits + r := t * t / x + s := C + r*t + t *= G + F/(s+E+D/s) + + // chop to 22 bits, make larger than cbrt(x) + t = Float64frombits(Float64bits(t)&(0xFFFFFFFFC<<28) + 1<<30) + + // one step newton iteration to 53 bits with error less than 0.667ulps + s = t * t // t*t is exact + r = x / s + w := t + t + r = (r - t) / (w + r) // r-s is exact + t = t + t*r + + // restore the sign bit + if sign { + t = -t + } + return t +} diff --git a/contrib/go/_std_1.18/src/math/const.go b/contrib/go/_std_1.18/src/math/const.go new file mode 100644 index 0000000000..5ea935fb42 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/const.go @@ -0,0 +1,57 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package math provides basic constants and mathematical functions. +// +// This package does not guarantee bit-identical results across architectures. +package math + +// Mathematical constants. +const ( + E = 2.71828182845904523536028747135266249775724709369995957496696763 // https://oeis.org/A001113 + Pi = 3.14159265358979323846264338327950288419716939937510582097494459 // https://oeis.org/A000796 + Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // https://oeis.org/A001622 + + Sqrt2 = 1.41421356237309504880168872420969807856967187537694807317667974 // https://oeis.org/A002193 + SqrtE = 1.64872127070012814684865078781416357165377610071014801157507931 // https://oeis.org/A019774 + SqrtPi = 1.77245385090551602729816748334114518279754945612238712821380779 // https://oeis.org/A002161 + SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // https://oeis.org/A139339 + + Ln2 = 0.693147180559945309417232121458176568075500134360255254120680009 // https://oeis.org/A002162 + Log2E = 1 / Ln2 + Ln10 = 2.30258509299404568401799145468436420760110148862877297603332790 // https://oeis.org/A002392 + Log10E = 1 / Ln10 +) + +// Floating-point limit values. +// Max is the largest finite value representable by the type. +// SmallestNonzero is the smallest positive, non-zero value representable by the type. +const ( + MaxFloat32 = 0x1p127 * (1 + (1 - 0x1p-23)) // 3.40282346638528859811704183484516925440e+38 + SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23 // 1.401298464324817070923729583289916131280e-45 + + MaxFloat64 = 0x1p1023 * (1 + (1 - 0x1p-52)) // 1.79769313486231570814527423731704356798070e+308 + SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 +) + +// Integer limit values. +const ( + intSize = 32 << (^uint(0) >> 63) // 32 or 64 + + MaxInt = 1<<(intSize-1) - 1 + MinInt = -1 << (intSize - 1) + MaxInt8 = 1<<7 - 1 + MinInt8 = -1 << 7 + MaxInt16 = 1<<15 - 1 + MinInt16 = -1 << 15 + MaxInt32 = 1<<31 - 1 + MinInt32 = -1 << 31 + MaxInt64 = 1<<63 - 1 + MinInt64 = -1 << 63 + MaxUint = 1<<intSize - 1 + MaxUint8 = 1<<8 - 1 + MaxUint16 = 1<<16 - 1 + MaxUint32 = 1<<32 - 1 + MaxUint64 = 1<<64 - 1 +) diff --git a/contrib/go/_std_1.18/src/math/copysign.go b/contrib/go/_std_1.18/src/math/copysign.go new file mode 100644 index 0000000000..719c64b9eb --- /dev/null +++ b/contrib/go/_std_1.18/src/math/copysign.go @@ -0,0 +1,12 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Copysign returns a value with the magnitude +// of x and the sign of y. +func Copysign(x, y float64) float64 { + const sign = 1 << 63 + return Float64frombits(Float64bits(x)&^sign | Float64bits(y)&sign) +} diff --git a/contrib/go/_std_1.18/src/math/dim.go b/contrib/go/_std_1.18/src/math/dim.go new file mode 100644 index 0000000000..6a857bbe41 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/dim.go @@ -0,0 +1,91 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Dim returns the maximum of x-y or 0. +// +// Special cases are: +// Dim(+Inf, +Inf) = NaN +// Dim(-Inf, -Inf) = NaN +// Dim(x, NaN) = Dim(NaN, x) = NaN +func Dim(x, y float64) float64 { + // The special cases result in NaN after the subtraction: + // +Inf - +Inf = NaN + // -Inf - -Inf = NaN + // NaN - y = NaN + // x - NaN = NaN + v := x - y + if v <= 0 { + // v is negative or 0 + return 0 + } + // v is positive or NaN + return v +} + +// Max returns the larger of x or y. +// +// Special cases are: +// Max(x, +Inf) = Max(+Inf, x) = +Inf +// Max(x, NaN) = Max(NaN, x) = NaN +// Max(+0, ±0) = Max(±0, +0) = +0 +// Max(-0, -0) = -0 +func Max(x, y float64) float64 { + if haveArchMax { + return archMax(x, y) + } + return max(x, y) +} + +func max(x, y float64) float64 { + // special cases + switch { + case IsInf(x, 1) || IsInf(y, 1): + return Inf(1) + case IsNaN(x) || IsNaN(y): + return NaN() + case x == 0 && x == y: + if Signbit(x) { + return y + } + return x + } + if x > y { + return x + } + return y +} + +// Min returns the smaller of x or y. +// +// Special cases are: +// Min(x, -Inf) = Min(-Inf, x) = -Inf +// Min(x, NaN) = Min(NaN, x) = NaN +// Min(-0, ±0) = Min(±0, -0) = -0 +func Min(x, y float64) float64 { + if haveArchMin { + return archMin(x, y) + } + return min(x, y) +} + +func min(x, y float64) float64 { + // special cases + switch { + case IsInf(x, -1) || IsInf(y, -1): + return Inf(-1) + case IsNaN(x) || IsNaN(y): + return NaN() + case x == 0 && x == y: + if Signbit(x) { + return x + } + return y + } + if x < y { + return x + } + return y +} diff --git a/contrib/go/_std_1.18/src/math/dim_amd64.s b/contrib/go/_std_1.18/src/math/dim_amd64.s new file mode 100644 index 0000000000..253f03b97e --- /dev/null +++ b/contrib/go/_std_1.18/src/math/dim_amd64.s @@ -0,0 +1,98 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +#define PosInf 0x7FF0000000000000 +#define NaN 0x7FF8000000000001 +#define NegInf 0xFFF0000000000000 + +// func ·archMax(x, y float64) float64 +TEXT ·archMax(SB),NOSPLIT,$0 + // +Inf special cases + MOVQ $PosInf, AX + MOVQ x+0(FP), R8 + CMPQ AX, R8 + JEQ isPosInf + MOVQ y+8(FP), R9 + CMPQ AX, R9 + JEQ isPosInf + // NaN special cases + MOVQ $~(1<<63), DX // bit mask + MOVQ $PosInf, AX + MOVQ R8, BX + ANDQ DX, BX // x = |x| + CMPQ AX, BX + JLT isMaxNaN + MOVQ R9, CX + ANDQ DX, CX // y = |y| + CMPQ AX, CX + JLT isMaxNaN + // ±0 special cases + ORQ CX, BX + JEQ isMaxZero + + MOVQ R8, X0 + MOVQ R9, X1 + MAXSD X1, X0 + MOVSD X0, ret+16(FP) + RET +isMaxNaN: // return NaN + MOVQ $NaN, AX +isPosInf: // return +Inf + MOVQ AX, ret+16(FP) + RET +isMaxZero: + MOVQ $(1<<63), AX // -0.0 + CMPQ AX, R8 + JEQ +3(PC) + MOVQ R8, ret+16(FP) // return 0 + RET + MOVQ R9, ret+16(FP) // return other 0 + RET + +// func archMin(x, y float64) float64 +TEXT ·archMin(SB),NOSPLIT,$0 + // -Inf special cases + MOVQ $NegInf, AX + MOVQ x+0(FP), R8 + CMPQ AX, R8 + JEQ isNegInf + MOVQ y+8(FP), R9 + CMPQ AX, R9 + JEQ isNegInf + // NaN special cases + MOVQ $~(1<<63), DX + MOVQ $PosInf, AX + MOVQ R8, BX + ANDQ DX, BX // x = |x| + CMPQ AX, BX + JLT isMinNaN + MOVQ R9, CX + ANDQ DX, CX // y = |y| + CMPQ AX, CX + JLT isMinNaN + // ±0 special cases + ORQ CX, BX + JEQ isMinZero + + MOVQ R8, X0 + MOVQ R9, X1 + MINSD X1, X0 + MOVSD X0, ret+16(FP) + RET +isMinNaN: // return NaN + MOVQ $NaN, AX +isNegInf: // return -Inf + MOVQ AX, ret+16(FP) + RET +isMinZero: + MOVQ $(1<<63), AX // -0.0 + CMPQ AX, R8 + JEQ +3(PC) + MOVQ R9, ret+16(FP) // return other 0 + RET + MOVQ R8, ret+16(FP) // return -0 + RET + diff --git a/contrib/go/_std_1.18/src/math/dim_asm.go b/contrib/go/_std_1.18/src/math/dim_asm.go new file mode 100644 index 0000000000..f4adbd0ae5 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/dim_asm.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 || arm64 || riscv64 || s390x + +package math + +const haveArchMax = true + +func archMax(x, y float64) float64 + +const haveArchMin = true + +func archMin(x, y float64) float64 diff --git a/contrib/go/_std_1.18/src/math/erf.go b/contrib/go/_std_1.18/src/math/erf.go new file mode 100644 index 0000000000..4d6fe472f1 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/erf.go @@ -0,0 +1,349 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point error function and complementary error function. +*/ + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/s_erf.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// +// double erf(double x) +// double erfc(double x) +// x +// 2 |\ +// erf(x) = --------- | exp(-t*t)dt +// sqrt(pi) \| +// 0 +// +// erfc(x) = 1-erf(x) +// Note that +// erf(-x) = -erf(x) +// erfc(-x) = 2 - erfc(x) +// +// Method: +// 1. For |x| in [0, 0.84375] +// erf(x) = x + x*R(x**2) +// erfc(x) = 1 - erf(x) if x in [-.84375,0.25] +// = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] +// where R = P/Q where P is an odd poly of degree 8 and +// Q is an odd poly of degree 10. +// -57.90 +// | R - (erf(x)-x)/x | <= 2 +// +// +// Remark. The formula is derived by noting +// erf(x) = (2/sqrt(pi))*(x - x**3/3 + x**5/10 - x**7/42 + ....) +// and that +// 2/sqrt(pi) = 1.128379167095512573896158903121545171688 +// is close to one. The interval is chosen because the fix +// point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is +// near 0.6174), and by some experiment, 0.84375 is chosen to +// guarantee the error is less than one ulp for erf. +// +// 2. For |x| in [0.84375,1.25], let s = |x| - 1, and +// c = 0.84506291151 rounded to single (24 bits) +// erf(x) = sign(x) * (c + P1(s)/Q1(s)) +// erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 +// 1+(c+P1(s)/Q1(s)) if x < 0 +// |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 +// Remark: here we use the taylor series expansion at x=1. +// erf(1+s) = erf(1) + s*Poly(s) +// = 0.845.. + P1(s)/Q1(s) +// That is, we use rational approximation to approximate +// erf(1+s) - (c = (single)0.84506291151) +// Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] +// where +// P1(s) = degree 6 poly in s +// Q1(s) = degree 6 poly in s +// +// 3. For x in [1.25,1/0.35(~2.857143)], +// erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) +// erf(x) = 1 - erfc(x) +// where +// R1(z) = degree 7 poly in z, (z=1/x**2) +// S1(z) = degree 8 poly in z +// +// 4. For x in [1/0.35,28] +// erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 +// = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0 +// = 2.0 - tiny (if x <= -6) +// erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else +// erf(x) = sign(x)*(1.0 - tiny) +// where +// R2(z) = degree 6 poly in z, (z=1/x**2) +// S2(z) = degree 7 poly in z +// +// Note1: +// To compute exp(-x*x-0.5625+R/S), let s be a single +// precision number and s := x; then +// -x*x = -s*s + (s-x)*(s+x) +// exp(-x*x-0.5626+R/S) = +// exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S); +// Note2: +// Here 4 and 5 make use of the asymptotic series +// exp(-x*x) +// erfc(x) ~ ---------- * ( 1 + Poly(1/x**2) ) +// x*sqrt(pi) +// We use rational approximation to approximate +// g(s)=f(1/x**2) = log(erfc(x)*x) - x*x + 0.5625 +// Here is the error bound for R1/S1 and R2/S2 +// |R1/S1 - f(x)| < 2**(-62.57) +// |R2/S2 - f(x)| < 2**(-61.52) +// +// 5. For inf > x >= 28 +// erf(x) = sign(x) *(1 - tiny) (raise inexact) +// erfc(x) = tiny*tiny (raise underflow) if x > 0 +// = 2 - tiny if x<0 +// +// 7. Special case: +// erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, +// erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, +// erfc/erf(NaN) is NaN + +const ( + erx = 8.45062911510467529297e-01 // 0x3FEB0AC160000000 + // Coefficients for approximation to erf in [0, 0.84375] + efx = 1.28379167095512586316e-01 // 0x3FC06EBA8214DB69 + efx8 = 1.02703333676410069053e+00 // 0x3FF06EBA8214DB69 + pp0 = 1.28379167095512558561e-01 // 0x3FC06EBA8214DB68 + pp1 = -3.25042107247001499370e-01 // 0xBFD4CD7D691CB913 + pp2 = -2.84817495755985104766e-02 // 0xBF9D2A51DBD7194F + pp3 = -5.77027029648944159157e-03 // 0xBF77A291236668E4 + pp4 = -2.37630166566501626084e-05 // 0xBEF8EAD6120016AC + qq1 = 3.97917223959155352819e-01 // 0x3FD97779CDDADC09 + qq2 = 6.50222499887672944485e-02 // 0x3FB0A54C5536CEBA + qq3 = 5.08130628187576562776e-03 // 0x3F74D022C4D36B0F + qq4 = 1.32494738004321644526e-04 // 0x3F215DC9221C1A10 + qq5 = -3.96022827877536812320e-06 // 0xBED09C4342A26120 + // Coefficients for approximation to erf in [0.84375, 1.25] + pa0 = -2.36211856075265944077e-03 // 0xBF6359B8BEF77538 + pa1 = 4.14856118683748331666e-01 // 0x3FDA8D00AD92B34D + pa2 = -3.72207876035701323847e-01 // 0xBFD7D240FBB8C3F1 + pa3 = 3.18346619901161753674e-01 // 0x3FD45FCA805120E4 + pa4 = -1.10894694282396677476e-01 // 0xBFBC63983D3E28EC + pa5 = 3.54783043256182359371e-02 // 0x3FA22A36599795EB + pa6 = -2.16637559486879084300e-03 // 0xBF61BF380A96073F + qa1 = 1.06420880400844228286e-01 // 0x3FBB3E6618EEE323 + qa2 = 5.40397917702171048937e-01 // 0x3FE14AF092EB6F33 + qa3 = 7.18286544141962662868e-02 // 0x3FB2635CD99FE9A7 + qa4 = 1.26171219808761642112e-01 // 0x3FC02660E763351F + qa5 = 1.36370839120290507362e-02 // 0x3F8BEDC26B51DD1C + qa6 = 1.19844998467991074170e-02 // 0x3F888B545735151D + // Coefficients for approximation to erfc in [1.25, 1/0.35] + ra0 = -9.86494403484714822705e-03 // 0xBF843412600D6435 + ra1 = -6.93858572707181764372e-01 // 0xBFE63416E4BA7360 + ra2 = -1.05586262253232909814e+01 // 0xC0251E0441B0E726 + ra3 = -6.23753324503260060396e+01 // 0xC04F300AE4CBA38D + ra4 = -1.62396669462573470355e+02 // 0xC0644CB184282266 + ra5 = -1.84605092906711035994e+02 // 0xC067135CEBCCABB2 + ra6 = -8.12874355063065934246e+01 // 0xC054526557E4D2F2 + ra7 = -9.81432934416914548592e+00 // 0xC023A0EFC69AC25C + sa1 = 1.96512716674392571292e+01 // 0x4033A6B9BD707687 + sa2 = 1.37657754143519042600e+02 // 0x4061350C526AE721 + sa3 = 4.34565877475229228821e+02 // 0x407B290DD58A1A71 + sa4 = 6.45387271733267880336e+02 // 0x40842B1921EC2868 + sa5 = 4.29008140027567833386e+02 // 0x407AD02157700314 + sa6 = 1.08635005541779435134e+02 // 0x405B28A3EE48AE2C + sa7 = 6.57024977031928170135e+00 // 0x401A47EF8E484A93 + sa8 = -6.04244152148580987438e-02 // 0xBFAEEFF2EE749A62 + // Coefficients for approximation to erfc in [1/.35, 28] + rb0 = -9.86494292470009928597e-03 // 0xBF84341239E86F4A + rb1 = -7.99283237680523006574e-01 // 0xBFE993BA70C285DE + rb2 = -1.77579549177547519889e+01 // 0xC031C209555F995A + rb3 = -1.60636384855821916062e+02 // 0xC064145D43C5ED98 + rb4 = -6.37566443368389627722e+02 // 0xC083EC881375F228 + rb5 = -1.02509513161107724954e+03 // 0xC09004616A2E5992 + rb6 = -4.83519191608651397019e+02 // 0xC07E384E9BDC383F + sb1 = 3.03380607434824582924e+01 // 0x403E568B261D5190 + sb2 = 3.25792512996573918826e+02 // 0x40745CAE221B9F0A + sb3 = 1.53672958608443695994e+03 // 0x409802EB189D5118 + sb4 = 3.19985821950859553908e+03 // 0x40A8FFB7688C246A + sb5 = 2.55305040643316442583e+03 // 0x40A3F219CEDF3BE6 + sb6 = 4.74528541206955367215e+02 // 0x407DA874E79FE763 + sb7 = -2.24409524465858183362e+01 // 0xC03670E242712D62 +) + +// Erf returns the error function of x. +// +// Special cases are: +// Erf(+Inf) = 1 +// Erf(-Inf) = -1 +// Erf(NaN) = NaN +func Erf(x float64) float64 { + if haveArchErf { + return archErf(x) + } + return erf(x) +} + +func erf(x float64) float64 { + const ( + VeryTiny = 2.848094538889218e-306 // 0x0080000000000000 + Small = 1.0 / (1 << 28) // 2**-28 + ) + // special cases + switch { + case IsNaN(x): + return NaN() + case IsInf(x, 1): + return 1 + case IsInf(x, -1): + return -1 + } + sign := false + if x < 0 { + x = -x + sign = true + } + if x < 0.84375 { // |x| < 0.84375 + var temp float64 + if x < Small { // |x| < 2**-28 + if x < VeryTiny { + temp = 0.125 * (8.0*x + efx8*x) // avoid underflow + } else { + temp = x + efx*x + } + } else { + z := x * x + r := pp0 + z*(pp1+z*(pp2+z*(pp3+z*pp4))) + s := 1 + z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))) + y := r / s + temp = x + x*y + } + if sign { + return -temp + } + return temp + } + if x < 1.25 { // 0.84375 <= |x| < 1.25 + s := x - 1 + P := pa0 + s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))) + Q := 1 + s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))) + if sign { + return -erx - P/Q + } + return erx + P/Q + } + if x >= 6 { // inf > |x| >= 6 + if sign { + return -1 + } + return 1 + } + s := 1 / (x * x) + var R, S float64 + if x < 1/0.35 { // |x| < 1 / 0.35 ~ 2.857143 + R = ra0 + s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*ra7)))))) + S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8))))))) + } else { // |x| >= 1 / 0.35 ~ 2.857143 + R = rb0 + s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6))))) + S = 1 + s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7)))))) + } + z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precision x + r := Exp(-z*z-0.5625) * Exp((z-x)*(z+x)+R/S) + if sign { + return r/x - 1 + } + return 1 - r/x +} + +// Erfc returns the complementary error function of x. +// +// Special cases are: +// Erfc(+Inf) = 0 +// Erfc(-Inf) = 2 +// Erfc(NaN) = NaN +func Erfc(x float64) float64 { + if haveArchErfc { + return archErfc(x) + } + return erfc(x) +} + +func erfc(x float64) float64 { + const Tiny = 1.0 / (1 << 56) // 2**-56 + // special cases + switch { + case IsNaN(x): + return NaN() + case IsInf(x, 1): + return 0 + case IsInf(x, -1): + return 2 + } + sign := false + if x < 0 { + x = -x + sign = true + } + if x < 0.84375 { // |x| < 0.84375 + var temp float64 + if x < Tiny { // |x| < 2**-56 + temp = x + } else { + z := x * x + r := pp0 + z*(pp1+z*(pp2+z*(pp3+z*pp4))) + s := 1 + z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))) + y := r / s + if x < 0.25 { // |x| < 1/4 + temp = x + x*y + } else { + temp = 0.5 + (x*y + (x - 0.5)) + } + } + if sign { + return 1 + temp + } + return 1 - temp + } + if x < 1.25 { // 0.84375 <= |x| < 1.25 + s := x - 1 + P := pa0 + s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))) + Q := 1 + s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))) + if sign { + return 1 + erx + P/Q + } + return 1 - erx - P/Q + + } + if x < 28 { // |x| < 28 + s := 1 / (x * x) + var R, S float64 + if x < 1/0.35 { // |x| < 1 / 0.35 ~ 2.857143 + R = ra0 + s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(ra5+s*(ra6+s*ra7)))))) + S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8))))))) + } else { // |x| >= 1 / 0.35 ~ 2.857143 + if sign && x > 6 { + return 2 // x < -6 + } + R = rb0 + s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+s*rb6))))) + S = 1 + s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(sb5+s*(sb6+s*sb7)))))) + } + z := Float64frombits(Float64bits(x) & 0xffffffff00000000) // pseudo-single (20-bit) precision x + r := Exp(-z*z-0.5625) * Exp((z-x)*(z+x)+R/S) + if sign { + return 2 - r/x + } + return r / x + } + if sign { + return 2 + } + return 0 +} diff --git a/contrib/go/_std_1.18/src/math/erfinv.go b/contrib/go/_std_1.18/src/math/erfinv.go new file mode 100644 index 0000000000..ee423d33e4 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/erfinv.go @@ -0,0 +1,127 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Inverse of the floating-point error function. +*/ + +// This implementation is based on the rational approximation +// of percentage points of normal distribution available from +// https://www.jstor.org/stable/2347330. + +const ( + // Coefficients for approximation to erf in |x| <= 0.85 + a0 = 1.1975323115670912564578e0 + a1 = 4.7072688112383978012285e1 + a2 = 6.9706266534389598238465e2 + a3 = 4.8548868893843886794648e3 + a4 = 1.6235862515167575384252e4 + a5 = 2.3782041382114385731252e4 + a6 = 1.1819493347062294404278e4 + a7 = 8.8709406962545514830200e2 + b0 = 1.0000000000000000000e0 + b1 = 4.2313330701600911252e1 + b2 = 6.8718700749205790830e2 + b3 = 5.3941960214247511077e3 + b4 = 2.1213794301586595867e4 + b5 = 3.9307895800092710610e4 + b6 = 2.8729085735721942674e4 + b7 = 5.2264952788528545610e3 + // Coefficients for approximation to erf in 0.85 < |x| <= 1-2*exp(-25) + c0 = 1.42343711074968357734e0 + c1 = 4.63033784615654529590e0 + c2 = 5.76949722146069140550e0 + c3 = 3.64784832476320460504e0 + c4 = 1.27045825245236838258e0 + c5 = 2.41780725177450611770e-1 + c6 = 2.27238449892691845833e-2 + c7 = 7.74545014278341407640e-4 + d0 = 1.4142135623730950488016887e0 + d1 = 2.9036514445419946173133295e0 + d2 = 2.3707661626024532365971225e0 + d3 = 9.7547832001787427186894837e-1 + d4 = 2.0945065210512749128288442e-1 + d5 = 2.1494160384252876777097297e-2 + d6 = 7.7441459065157709165577218e-4 + d7 = 1.4859850019840355905497876e-9 + // Coefficients for approximation to erf in 1-2*exp(-25) < |x| < 1 + e0 = 6.65790464350110377720e0 + e1 = 5.46378491116411436990e0 + e2 = 1.78482653991729133580e0 + e3 = 2.96560571828504891230e-1 + e4 = 2.65321895265761230930e-2 + e5 = 1.24266094738807843860e-3 + e6 = 2.71155556874348757815e-5 + e7 = 2.01033439929228813265e-7 + f0 = 1.414213562373095048801689e0 + f1 = 8.482908416595164588112026e-1 + f2 = 1.936480946950659106176712e-1 + f3 = 2.103693768272068968719679e-2 + f4 = 1.112800997078859844711555e-3 + f5 = 2.611088405080593625138020e-5 + f6 = 2.010321207683943062279931e-7 + f7 = 2.891024605872965461538222e-15 +) + +// Erfinv returns the inverse error function of x. +// +// Special cases are: +// Erfinv(1) = +Inf +// Erfinv(-1) = -Inf +// Erfinv(x) = NaN if x < -1 or x > 1 +// Erfinv(NaN) = NaN +func Erfinv(x float64) float64 { + // special cases + if IsNaN(x) || x <= -1 || x >= 1 { + if x == -1 || x == 1 { + return Inf(int(x)) + } + return NaN() + } + + sign := false + if x < 0 { + x = -x + sign = true + } + + var ans float64 + if x <= 0.85 { // |x| <= 0.85 + r := 0.180625 - 0.25*x*x + z1 := ((((((a7*r+a6)*r+a5)*r+a4)*r+a3)*r+a2)*r+a1)*r + a0 + z2 := ((((((b7*r+b6)*r+b5)*r+b4)*r+b3)*r+b2)*r+b1)*r + b0 + ans = (x * z1) / z2 + } else { + var z1, z2 float64 + r := Sqrt(Ln2 - Log(1.0-x)) + if r <= 5.0 { + r -= 1.6 + z1 = ((((((c7*r+c6)*r+c5)*r+c4)*r+c3)*r+c2)*r+c1)*r + c0 + z2 = ((((((d7*r+d6)*r+d5)*r+d4)*r+d3)*r+d2)*r+d1)*r + d0 + } else { + r -= 5.0 + z1 = ((((((e7*r+e6)*r+e5)*r+e4)*r+e3)*r+e2)*r+e1)*r + e0 + z2 = ((((((f7*r+f6)*r+f5)*r+f4)*r+f3)*r+f2)*r+f1)*r + f0 + } + ans = z1 / z2 + } + + if sign { + return -ans + } + return ans +} + +// Erfcinv returns the inverse of Erfc(x). +// +// Special cases are: +// Erfcinv(0) = +Inf +// Erfcinv(2) = -Inf +// Erfcinv(x) = NaN if x < 0 or x > 2 +// Erfcinv(NaN) = NaN +func Erfcinv(x float64) float64 { + return Erfinv(1 - x) +} diff --git a/contrib/go/_std_1.18/src/math/exp.go b/contrib/go/_std_1.18/src/math/exp.go new file mode 100644 index 0000000000..d05eb91fb0 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/exp.go @@ -0,0 +1,201 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Exp returns e**x, the base-e exponential of x. +// +// Special cases are: +// Exp(+Inf) = +Inf +// Exp(NaN) = NaN +// Very large values overflow to 0 or +Inf. +// Very small values underflow to 1. +func Exp(x float64) float64 { + if haveArchExp { + return archExp(x) + } + return exp(x) +} + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/e_exp.c +// and came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. +// +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// +// exp(x) +// Returns the exponential of x. +// +// Method +// 1. Argument reduction: +// Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. +// Given x, find r and integer k such that +// +// x = k*ln2 + r, |r| <= 0.5*ln2. +// +// Here r will be represented as r = hi-lo for better +// accuracy. +// +// 2. Approximation of exp(r) by a special rational function on +// the interval [0,0.34658]: +// Write +// R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... +// We use a special Remez algorithm on [0,0.34658] to generate +// a polynomial of degree 5 to approximate R. The maximum error +// of this polynomial approximation is bounded by 2**-59. In +// other words, +// R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 +// (where z=r*r, and the values of P1 to P5 are listed below) +// and +// | 5 | -59 +// | 2.0+P1*z+...+P5*z - R(z) | <= 2 +// | | +// The computation of exp(r) thus becomes +// 2*r +// exp(r) = 1 + ------- +// R - r +// r*R1(r) +// = 1 + r + ----------- (for better accuracy) +// 2 - R1(r) +// where +// 2 4 10 +// R1(r) = r - (P1*r + P2*r + ... + P5*r ). +// +// 3. Scale back to obtain exp(x): +// From step 1, we have +// exp(x) = 2**k * exp(r) +// +// Special cases: +// exp(INF) is INF, exp(NaN) is NaN; +// exp(-INF) is 0, and +// for finite argument, only exp(0)=1 is exact. +// +// Accuracy: +// according to an error analysis, the error is always less than +// 1 ulp (unit in the last place). +// +// Misc. info. +// For IEEE double +// if x > 7.09782712893383973096e+02 then exp(x) overflow +// if x < -7.45133219101941108420e+02 then exp(x) underflow +// +// Constants: +// The hexadecimal values are the intended ones for the following +// constants. The decimal values may be used, provided that the +// compiler will convert from decimal to binary accurately enough +// to produce the hexadecimal values shown. + +func exp(x float64) float64 { + const ( + Ln2Hi = 6.93147180369123816490e-01 + Ln2Lo = 1.90821492927058770002e-10 + Log2e = 1.44269504088896338700e+00 + + Overflow = 7.09782712893383973096e+02 + Underflow = -7.45133219101941108420e+02 + NearZero = 1.0 / (1 << 28) // 2**-28 + ) + + // special cases + switch { + case IsNaN(x) || IsInf(x, 1): + return x + case IsInf(x, -1): + return 0 + case x > Overflow: + return Inf(1) + case x < Underflow: + return 0 + case -NearZero < x && x < NearZero: + return 1 + x + } + + // reduce; computed as r = hi - lo for extra precision. + var k int + switch { + case x < 0: + k = int(Log2e*x - 0.5) + case x > 0: + k = int(Log2e*x + 0.5) + } + hi := x - float64(k)*Ln2Hi + lo := float64(k) * Ln2Lo + + // compute + return expmulti(hi, lo, k) +} + +// Exp2 returns 2**x, the base-2 exponential of x. +// +// Special cases are the same as Exp. +func Exp2(x float64) float64 { + if haveArchExp2 { + return archExp2(x) + } + return exp2(x) +} + +func exp2(x float64) float64 { + const ( + Ln2Hi = 6.93147180369123816490e-01 + Ln2Lo = 1.90821492927058770002e-10 + + Overflow = 1.0239999999999999e+03 + Underflow = -1.0740e+03 + ) + + // special cases + switch { + case IsNaN(x) || IsInf(x, 1): + return x + case IsInf(x, -1): + return 0 + case x > Overflow: + return Inf(1) + case x < Underflow: + return 0 + } + + // argument reduction; x = r×lg(e) + k with |r| ≤ ln(2)/2. + // computed as r = hi - lo for extra precision. + var k int + switch { + case x > 0: + k = int(x + 0.5) + case x < 0: + k = int(x - 0.5) + } + t := x - float64(k) + hi := t * Ln2Hi + lo := -t * Ln2Lo + + // compute + return expmulti(hi, lo, k) +} + +// exp1 returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2. +func expmulti(hi, lo float64, k int) float64 { + const ( + P1 = 1.66666666666666657415e-01 /* 0x3FC55555; 0x55555555 */ + P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */ + P3 = 6.61375632143793436117e-05 /* 0x3F11566A; 0xAF25DE2C */ + P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */ + P5 = 4.13813679705723846039e-08 /* 0x3E663769; 0x72BEA4D0 */ + ) + + r := hi - lo + t := r * r + c := r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))) + y := 1 - ((lo - (r*c)/(2-c)) - hi) + // TODO(rsc): make sure Ldexp can handle boundary k + return Ldexp(y, k) +} diff --git a/contrib/go/_std_1.18/src/math/exp2_noasm.go b/contrib/go/_std_1.18/src/math/exp2_noasm.go new file mode 100644 index 0000000000..c2b409329f --- /dev/null +++ b/contrib/go/_std_1.18/src/math/exp2_noasm.go @@ -0,0 +1,13 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !arm64 + +package math + +const haveArchExp2 = false + +func archExp2(x float64) float64 { + panic("not implemented") +} diff --git a/contrib/go/_std_1.18/src/math/exp_amd64.go b/contrib/go/_std_1.18/src/math/exp_amd64.go new file mode 100644 index 0000000000..0f701b1d6d --- /dev/null +++ b/contrib/go/_std_1.18/src/math/exp_amd64.go @@ -0,0 +1,11 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 + +package math + +import "internal/cpu" + +var useFMA = cpu.X86.HasAVX && cpu.X86.HasFMA diff --git a/contrib/go/_std_1.18/src/math/exp_amd64.s b/contrib/go/_std_1.18/src/math/exp_amd64.s new file mode 100644 index 0000000000..02b71c81eb --- /dev/null +++ b/contrib/go/_std_1.18/src/math/exp_amd64.s @@ -0,0 +1,159 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +// The method is based on a paper by Naoki Shibata: "Efficient evaluation +// methods of elementary functions suitable for SIMD computation", Proc. +// of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32 +// (May 2010). The paper is available at +// https://link.springer.com/article/10.1007/s00450-010-0108-2 +// +// The original code and the constants below are from the author's +// implementation available at http://freshmeat.net/projects/sleef. +// The README file says, "The software is in public domain. +// You can use the software without any obligation." +// +// This code is a simplified version of the original. + +#define LN2 0.6931471805599453094172321214581766 // log_e(2) +#define LOG2E 1.4426950408889634073599246810018920 // 1/LN2 +#define LN2U 0.69314718055966295651160180568695068359375 // upper half LN2 +#define LN2L 0.28235290563031577122588448175013436025525412068e-12 // lower half LN2 +#define PosInf 0x7FF0000000000000 +#define NegInf 0xFFF0000000000000 +#define Overflow 7.09782712893384e+02 + +DATA exprodata<>+0(SB)/8, $0.5 +DATA exprodata<>+8(SB)/8, $1.0 +DATA exprodata<>+16(SB)/8, $2.0 +DATA exprodata<>+24(SB)/8, $1.6666666666666666667e-1 +DATA exprodata<>+32(SB)/8, $4.1666666666666666667e-2 +DATA exprodata<>+40(SB)/8, $8.3333333333333333333e-3 +DATA exprodata<>+48(SB)/8, $1.3888888888888888889e-3 +DATA exprodata<>+56(SB)/8, $1.9841269841269841270e-4 +DATA exprodata<>+64(SB)/8, $2.4801587301587301587e-5 +GLOBL exprodata<>+0(SB), RODATA, $72 + +// func Exp(x float64) float64 +TEXT ·archExp(SB),NOSPLIT,$0 + // test bits for not-finite + MOVQ x+0(FP), BX + MOVQ $~(1<<63), AX // sign bit mask + MOVQ BX, DX + ANDQ AX, DX + MOVQ $PosInf, AX + CMPQ AX, DX + JLE notFinite + // check if argument will overflow + MOVQ BX, X0 + MOVSD $Overflow, X1 + COMISD X1, X0 + JA overflow + MOVSD $LOG2E, X1 + MULSD X0, X1 + CVTSD2SL X1, BX // BX = exponent + CVTSL2SD BX, X1 + CMPB ·useFMA(SB), $1 + JE avxfma + MOVSD $LN2U, X2 + MULSD X1, X2 + SUBSD X2, X0 + MOVSD $LN2L, X2 + MULSD X1, X2 + SUBSD X2, X0 + // reduce argument + MULSD $0.0625, X0 + // Taylor series evaluation + MOVSD exprodata<>+64(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+56(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+48(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+40(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+32(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+24(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+0(SB), X1 + MULSD X0, X1 + ADDSD exprodata<>+8(SB), X1 + MULSD X1, X0 + MOVSD exprodata<>+16(SB), X1 + ADDSD X0, X1 + MULSD X1, X0 + MOVSD exprodata<>+16(SB), X1 + ADDSD X0, X1 + MULSD X1, X0 + MOVSD exprodata<>+16(SB), X1 + ADDSD X0, X1 + MULSD X1, X0 + MOVSD exprodata<>+16(SB), X1 + ADDSD X0, X1 + MULSD X1, X0 + ADDSD exprodata<>+8(SB), X0 + // return fr * 2**exponent +ldexp: + ADDL $0x3FF, BX // add bias + JLE denormal + CMPL BX, $0x7FF + JGE overflow +lastStep: + SHLQ $52, BX + MOVQ BX, X1 + MULSD X1, X0 + MOVSD X0, ret+8(FP) + RET +notFinite: + // test bits for -Inf + MOVQ $NegInf, AX + CMPQ AX, BX + JNE notNegInf + // -Inf, return 0 +underflow: // return 0 + MOVQ $0, ret+8(FP) + RET +overflow: // return +Inf + MOVQ $PosInf, BX +notNegInf: // NaN or +Inf, return x + MOVQ BX, ret+8(FP) + RET +denormal: + CMPL BX, $-52 + JL underflow + ADDL $0x3FE, BX // add bias - 1 + SHLQ $52, BX + MOVQ BX, X1 + MULSD X1, X0 + MOVQ $1, BX + JMP lastStep + +avxfma: + MOVSD $LN2U, X2 + VFNMADD231SD X2, X1, X0 + MOVSD $LN2L, X2 + VFNMADD231SD X2, X1, X0 + // reduce argument + MULSD $0.0625, X0 + // Taylor series evaluation + MOVSD exprodata<>+64(SB), X1 + VFMADD213SD exprodata<>+56(SB), X0, X1 + VFMADD213SD exprodata<>+48(SB), X0, X1 + VFMADD213SD exprodata<>+40(SB), X0, X1 + VFMADD213SD exprodata<>+32(SB), X0, X1 + VFMADD213SD exprodata<>+24(SB), X0, X1 + VFMADD213SD exprodata<>+0(SB), X0, X1 + VFMADD213SD exprodata<>+8(SB), X0, X1 + MULSD X1, X0 + VADDSD exprodata<>+16(SB), X0, X1 + MULSD X1, X0 + VADDSD exprodata<>+16(SB), X0, X1 + MULSD X1, X0 + VADDSD exprodata<>+16(SB), X0, X1 + MULSD X1, X0 + VADDSD exprodata<>+16(SB), X0, X1 + VFMADD213SD exprodata<>+8(SB), X1, X0 + JMP ldexp diff --git a/contrib/go/_std_1.18/src/math/exp_asm.go b/contrib/go/_std_1.18/src/math/exp_asm.go new file mode 100644 index 0000000000..424442845b --- /dev/null +++ b/contrib/go/_std_1.18/src/math/exp_asm.go @@ -0,0 +1,11 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 || arm64 || s390x + +package math + +const haveArchExp = true + +func archExp(x float64) float64 diff --git a/contrib/go/_std_1.18/src/math/expm1.go b/contrib/go/_std_1.18/src/math/expm1.go new file mode 100644 index 0000000000..66d3421661 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/expm1.go @@ -0,0 +1,242 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/s_expm1.c +// and came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// expm1(x) +// Returns exp(x)-1, the exponential of x minus 1. +// +// Method +// 1. Argument reduction: +// Given x, find r and integer k such that +// +// x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 +// +// Here a correction term c will be computed to compensate +// the error in r when rounded to a floating-point number. +// +// 2. Approximating expm1(r) by a special rational function on +// the interval [0,0.34658]: +// Since +// r*(exp(r)+1)/(exp(r)-1) = 2+ r**2/6 - r**4/360 + ... +// we define R1(r*r) by +// r*(exp(r)+1)/(exp(r)-1) = 2+ r**2/6 * R1(r*r) +// That is, +// R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) +// = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) +// = 1 - r**2/60 + r**4/2520 - r**6/100800 + ... +// We use a special Reme algorithm on [0,0.347] to generate +// a polynomial of degree 5 in r*r to approximate R1. The +// maximum error of this polynomial approximation is bounded +// by 2**-61. In other words, +// R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 +// where Q1 = -1.6666666666666567384E-2, +// Q2 = 3.9682539681370365873E-4, +// Q3 = -9.9206344733435987357E-6, +// Q4 = 2.5051361420808517002E-7, +// Q5 = -6.2843505682382617102E-9; +// (where z=r*r, and the values of Q1 to Q5 are listed below) +// with error bounded by +// | 5 | -61 +// | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 +// | | +// +// expm1(r) = exp(r)-1 is then computed by the following +// specific way which minimize the accumulation rounding error: +// 2 3 +// r r [ 3 - (R1 + R1*r/2) ] +// expm1(r) = r + --- + --- * [--------------------] +// 2 2 [ 6 - r*(3 - R1*r/2) ] +// +// To compensate the error in the argument reduction, we use +// expm1(r+c) = expm1(r) + c + expm1(r)*c +// ~ expm1(r) + c + r*c +// Thus c+r*c will be added in as the correction terms for +// expm1(r+c). Now rearrange the term to avoid optimization +// screw up: +// ( 2 2 ) +// ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) +// expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) +// ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) +// ( ) +// +// = r - E +// 3. Scale back to obtain expm1(x): +// From step 1, we have +// expm1(x) = either 2**k*[expm1(r)+1] - 1 +// = or 2**k*[expm1(r) + (1-2**-k)] +// 4. Implementation notes: +// (A). To save one multiplication, we scale the coefficient Qi +// to Qi*2**i, and replace z by (x**2)/2. +// (B). To achieve maximum accuracy, we compute expm1(x) by +// (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) +// (ii) if k=0, return r-E +// (iii) if k=-1, return 0.5*(r-E)-0.5 +// (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) +// else return 1.0+2.0*(r-E); +// (v) if (k<-2||k>56) return 2**k(1-(E-r)) - 1 (or exp(x)-1) +// (vi) if k <= 20, return 2**k((1-2**-k)-(E-r)), else +// (vii) return 2**k(1-((E+2**-k)-r)) +// +// Special cases: +// expm1(INF) is INF, expm1(NaN) is NaN; +// expm1(-INF) is -1, and +// for finite argument, only expm1(0)=0 is exact. +// +// Accuracy: +// according to an error analysis, the error is always less than +// 1 ulp (unit in the last place). +// +// Misc. info. +// For IEEE double +// if x > 7.09782712893383973096e+02 then expm1(x) overflow +// +// Constants: +// The hexadecimal values are the intended ones for the following +// constants. The decimal values may be used, provided that the +// compiler will convert from decimal to binary accurately enough +// to produce the hexadecimal values shown. +// + +// Expm1 returns e**x - 1, the base-e exponential of x minus 1. +// It is more accurate than Exp(x) - 1 when x is near zero. +// +// Special cases are: +// Expm1(+Inf) = +Inf +// Expm1(-Inf) = -1 +// Expm1(NaN) = NaN +// Very large values overflow to -1 or +Inf. +func Expm1(x float64) float64 { + if haveArchExpm1 { + return archExpm1(x) + } + return expm1(x) +} + +func expm1(x float64) float64 { + const ( + Othreshold = 7.09782712893383973096e+02 // 0x40862E42FEFA39EF + Ln2X56 = 3.88162421113569373274e+01 // 0x4043687a9f1af2b1 + Ln2HalfX3 = 1.03972077083991796413e+00 // 0x3ff0a2b23f3bab73 + Ln2Half = 3.46573590279972654709e-01 // 0x3fd62e42fefa39ef + Ln2Hi = 6.93147180369123816490e-01 // 0x3fe62e42fee00000 + Ln2Lo = 1.90821492927058770002e-10 // 0x3dea39ef35793c76 + InvLn2 = 1.44269504088896338700e+00 // 0x3ff71547652b82fe + Tiny = 1.0 / (1 << 54) // 2**-54 = 0x3c90000000000000 + // scaled coefficients related to expm1 + Q1 = -3.33333333333331316428e-02 // 0xBFA11111111110F4 + Q2 = 1.58730158725481460165e-03 // 0x3F5A01A019FE5585 + Q3 = -7.93650757867487942473e-05 // 0xBF14CE199EAADBB7 + Q4 = 4.00821782732936239552e-06 // 0x3ED0CFCA86E65239 + Q5 = -2.01099218183624371326e-07 // 0xBE8AFDB76E09C32D + ) + + // special cases + switch { + case IsInf(x, 1) || IsNaN(x): + return x + case IsInf(x, -1): + return -1 + } + + absx := x + sign := false + if x < 0 { + absx = -absx + sign = true + } + + // filter out huge argument + if absx >= Ln2X56 { // if |x| >= 56 * ln2 + if sign { + return -1 // x < -56*ln2, return -1 + } + if absx >= Othreshold { // if |x| >= 709.78... + return Inf(1) + } + } + + // argument reduction + var c float64 + var k int + if absx > Ln2Half { // if |x| > 0.5 * ln2 + var hi, lo float64 + if absx < Ln2HalfX3 { // and |x| < 1.5 * ln2 + if !sign { + hi = x - Ln2Hi + lo = Ln2Lo + k = 1 + } else { + hi = x + Ln2Hi + lo = -Ln2Lo + k = -1 + } + } else { + if !sign { + k = int(InvLn2*x + 0.5) + } else { + k = int(InvLn2*x - 0.5) + } + t := float64(k) + hi = x - t*Ln2Hi // t * Ln2Hi is exact here + lo = t * Ln2Lo + } + x = hi - lo + c = (hi - x) - lo + } else if absx < Tiny { // when |x| < 2**-54, return x + return x + } else { + k = 0 + } + + // x is now in primary range + hfx := 0.5 * x + hxs := x * hfx + r1 := 1 + hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))) + t := 3 - r1*hfx + e := hxs * ((r1 - t) / (6.0 - x*t)) + if k == 0 { + return x - (x*e - hxs) // c is 0 + } + e = (x*(e-c) - c) + e -= hxs + switch { + case k == -1: + return 0.5*(x-e) - 0.5 + case k == 1: + if x < -0.25 { + return -2 * (e - (x + 0.5)) + } + return 1 + 2*(x-e) + case k <= -2 || k > 56: // suffice to return exp(x)-1 + y := 1 - (e - x) + y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent + return y - 1 + } + if k < 20 { + t := Float64frombits(0x3ff0000000000000 - (0x20000000000000 >> uint(k))) // t=1-2**-k + y := t - (e - x) + y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent + return y + } + t = Float64frombits(uint64(0x3ff-k) << 52) // 2**-k + y := x - (e + t) + y++ + y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent + return y +} diff --git a/contrib/go/_std_1.18/src/math/floor.go b/contrib/go/_std_1.18/src/math/floor.go new file mode 100644 index 0000000000..7913a900e3 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/floor.go @@ -0,0 +1,146 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Floor returns the greatest integer value less than or equal to x. +// +// Special cases are: +// Floor(±0) = ±0 +// Floor(±Inf) = ±Inf +// Floor(NaN) = NaN +func Floor(x float64) float64 { + if haveArchFloor { + return archFloor(x) + } + return floor(x) +} + +func floor(x float64) float64 { + if x == 0 || IsNaN(x) || IsInf(x, 0) { + return x + } + if x < 0 { + d, fract := Modf(-x) + if fract != 0.0 { + d = d + 1 + } + return -d + } + d, _ := Modf(x) + return d +} + +// Ceil returns the least integer value greater than or equal to x. +// +// Special cases are: +// Ceil(±0) = ±0 +// Ceil(±Inf) = ±Inf +// Ceil(NaN) = NaN +func Ceil(x float64) float64 { + if haveArchCeil { + return archCeil(x) + } + return ceil(x) +} + +func ceil(x float64) float64 { + return -Floor(-x) +} + +// Trunc returns the integer value of x. +// +// Special cases are: +// Trunc(±0) = ±0 +// Trunc(±Inf) = ±Inf +// Trunc(NaN) = NaN +func Trunc(x float64) float64 { + if haveArchTrunc { + return archTrunc(x) + } + return trunc(x) +} + +func trunc(x float64) float64 { + if x == 0 || IsNaN(x) || IsInf(x, 0) { + return x + } + d, _ := Modf(x) + return d +} + +// Round returns the nearest integer, rounding half away from zero. +// +// Special cases are: +// Round(±0) = ±0 +// Round(±Inf) = ±Inf +// Round(NaN) = NaN +func Round(x float64) float64 { + // Round is a faster implementation of: + // + // func Round(x float64) float64 { + // t := Trunc(x) + // if Abs(x-t) >= 0.5 { + // return t + Copysign(1, x) + // } + // return t + // } + bits := Float64bits(x) + e := uint(bits>>shift) & mask + if e < bias { + // Round abs(x) < 1 including denormals. + bits &= signMask // +-0 + if e == bias-1 { + bits |= uvone // +-1 + } + } else if e < bias+shift { + // Round any abs(x) >= 1 containing a fractional component [0,1). + // + // Numbers with larger exponents are returned unchanged since they + // must be either an integer, infinity, or NaN. + const half = 1 << (shift - 1) + e -= bias + bits += half >> e + bits &^= fracMask >> e + } + return Float64frombits(bits) +} + +// RoundToEven returns the nearest integer, rounding ties to even. +// +// Special cases are: +// RoundToEven(±0) = ±0 +// RoundToEven(±Inf) = ±Inf +// RoundToEven(NaN) = NaN +func RoundToEven(x float64) float64 { + // RoundToEven is a faster implementation of: + // + // func RoundToEven(x float64) float64 { + // t := math.Trunc(x) + // odd := math.Remainder(t, 2) != 0 + // if d := math.Abs(x - t); d > 0.5 || (d == 0.5 && odd) { + // return t + math.Copysign(1, x) + // } + // return t + // } + bits := Float64bits(x) + e := uint(bits>>shift) & mask + if e >= bias { + // Round abs(x) >= 1. + // - Large numbers without fractional components, infinity, and NaN are unchanged. + // - Add 0.499.. or 0.5 before truncating depending on whether the truncated + // number is even or odd (respectively). + const halfMinusULP = (1 << (shift - 1)) - 1 + e -= bias + bits += (halfMinusULP + (bits>>(shift-e))&1) >> e + bits &^= fracMask >> e + } else if e == bias-1 && bits&fracMask != 0 { + // Round 0.5 < abs(x) < 1. + bits = bits&signMask | uvone // +-1 + } else { + // Round abs(x) <= 0.5 including denormals. + bits &= signMask // +-0 + } + return Float64frombits(bits) +} diff --git a/contrib/go/_std_1.18/src/math/floor_amd64.s b/contrib/go/_std_1.18/src/math/floor_amd64.s new file mode 100644 index 0000000000..088049958a --- /dev/null +++ b/contrib/go/_std_1.18/src/math/floor_amd64.s @@ -0,0 +1,76 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +#define Big 0x4330000000000000 // 2**52 + +// func archFloor(x float64) float64 +TEXT ·archFloor(SB),NOSPLIT,$0 + MOVQ x+0(FP), AX + MOVQ $~(1<<63), DX // sign bit mask + ANDQ AX,DX // DX = |x| + SUBQ $1,DX + MOVQ $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x + CMPQ DX,CX + JAE isBig_floor + MOVQ AX, X0 // X0 = x + CVTTSD2SQ X0, AX + CVTSQ2SD AX, X1 // X1 = float(int(x)) + CMPSD X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0 + MOVSD $(-1.0), X2 + ANDPD X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0} + ADDSD X1, X0 + MOVSD X0, ret+8(FP) + RET +isBig_floor: + MOVQ AX, ret+8(FP) // return x + RET + +// func archCeil(x float64) float64 +TEXT ·archCeil(SB),NOSPLIT,$0 + MOVQ x+0(FP), AX + MOVQ $~(1<<63), DX // sign bit mask + MOVQ AX, BX // BX = copy of x + ANDQ DX, BX // BX = |x| + MOVQ $Big, CX // if |x| >= 2**52 or IsNaN(x), return x + CMPQ BX, CX + JAE isBig_ceil + MOVQ AX, X0 // X0 = x + MOVQ DX, X2 // X2 = sign bit mask + CVTTSD2SQ X0, AX + ANDNPD X0, X2 // X2 = sign + CVTSQ2SD AX, X1 // X1 = float(int(x)) + CMPSD X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0 + ORPD X2, X1 // if X1 = 0.0, incorporate sign + MOVSD $1.0, X3 + ANDNPD X3, X0 + ORPD X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0} + ADDSD X1, X0 + MOVSD X0, ret+8(FP) + RET +isBig_ceil: + MOVQ AX, ret+8(FP) + RET + +// func archTrunc(x float64) float64 +TEXT ·archTrunc(SB),NOSPLIT,$0 + MOVQ x+0(FP), AX + MOVQ $~(1<<63), DX // sign bit mask + MOVQ AX, BX // BX = copy of x + ANDQ DX, BX // BX = |x| + MOVQ $Big, CX // if |x| >= 2**52 or IsNaN(x), return x + CMPQ BX, CX + JAE isBig_trunc + MOVQ AX, X0 + MOVQ DX, X2 // X2 = sign bit mask + CVTTSD2SQ X0, AX + ANDNPD X0, X2 // X2 = sign + CVTSQ2SD AX, X0 // X0 = float(int(x)) + ORPD X2, X0 // if X0 = 0.0, incorporate sign + MOVSD X0, ret+8(FP) + RET +isBig_trunc: + MOVQ AX, ret+8(FP) // return x + RET diff --git a/contrib/go/_std_1.18/src/math/floor_asm.go b/contrib/go/_std_1.18/src/math/floor_asm.go new file mode 100644 index 0000000000..fb419d6da2 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/floor_asm.go @@ -0,0 +1,19 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build 386 || amd64 || arm64 || ppc64 || ppc64le || s390x || wasm + +package math + +const haveArchFloor = true + +func archFloor(x float64) float64 + +const haveArchCeil = true + +func archCeil(x float64) float64 + +const haveArchTrunc = true + +func archTrunc(x float64) float64 diff --git a/contrib/go/_std_1.18/src/math/fma.go b/contrib/go/_std_1.18/src/math/fma.go new file mode 100644 index 0000000000..ca0bf99f21 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/fma.go @@ -0,0 +1,170 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +import "math/bits" + +func zero(x uint64) uint64 { + if x == 0 { + return 1 + } + return 0 + // branchless: + // return ((x>>1 | x&1) - 1) >> 63 +} + +func nonzero(x uint64) uint64 { + if x != 0 { + return 1 + } + return 0 + // branchless: + // return 1 - ((x>>1|x&1)-1)>>63 +} + +func shl(u1, u2 uint64, n uint) (r1, r2 uint64) { + r1 = u1<<n | u2>>(64-n) | u2<<(n-64) + r2 = u2 << n + return +} + +func shr(u1, u2 uint64, n uint) (r1, r2 uint64) { + r2 = u2>>n | u1<<(64-n) | u1>>(n-64) + r1 = u1 >> n + return +} + +// shrcompress compresses the bottom n+1 bits of the two-word +// value into a single bit. the result is equal to the value +// shifted to the right by n, except the result's 0th bit is +// set to the bitwise OR of the bottom n+1 bits. +func shrcompress(u1, u2 uint64, n uint) (r1, r2 uint64) { + // TODO: Performance here is really sensitive to the + // order/placement of these branches. n == 0 is common + // enough to be in the fast path. Perhaps more measurement + // needs to be done to find the optimal order/placement? + switch { + case n == 0: + return u1, u2 + case n == 64: + return 0, u1 | nonzero(u2) + case n >= 128: + return 0, nonzero(u1 | u2) + case n < 64: + r1, r2 = shr(u1, u2, n) + r2 |= nonzero(u2 & (1<<n - 1)) + case n < 128: + r1, r2 = shr(u1, u2, n) + r2 |= nonzero(u1&(1<<(n-64)-1) | u2) + } + return +} + +func lz(u1, u2 uint64) (l int32) { + l = int32(bits.LeadingZeros64(u1)) + if l == 64 { + l += int32(bits.LeadingZeros64(u2)) + } + return l +} + +// split splits b into sign, biased exponent, and mantissa. +// It adds the implicit 1 bit to the mantissa for normal values, +// and normalizes subnormal values. +func split(b uint64) (sign uint32, exp int32, mantissa uint64) { + sign = uint32(b >> 63) + exp = int32(b>>52) & mask + mantissa = b & fracMask + + if exp == 0 { + // Normalize value if subnormal. + shift := uint(bits.LeadingZeros64(mantissa) - 11) + mantissa <<= shift + exp = 1 - int32(shift) + } else { + // Add implicit 1 bit + mantissa |= 1 << 52 + } + return +} + +// FMA returns x * y + z, computed with only one rounding. +// (That is, FMA returns the fused multiply-add of x, y, and z.) +func FMA(x, y, z float64) float64 { + bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z) + + // Inf or NaN or zero involved. At most one rounding will occur. + if x == 0.0 || y == 0.0 || z == 0.0 || bx&uvinf == uvinf || by&uvinf == uvinf { + return x*y + z + } + // Handle non-finite z separately. Evaluating x*y+z where + // x and y are finite, but z is infinite, should always result in z. + if bz&uvinf == uvinf { + return z + } + + // Inputs are (sub)normal. + // Split x, y, z into sign, exponent, mantissa. + xs, xe, xm := split(bx) + ys, ye, ym := split(by) + zs, ze, zm := split(bz) + + // Compute product p = x*y as sign, exponent, two-word mantissa. + // Start with exponent. "is normal" bit isn't subtracted yet. + pe := xe + ye - bias + 1 + + // pm1:pm2 is the double-word mantissa for the product p. + // Shift left to leave top bit in product. Effectively + // shifts the 106-bit product to the left by 21. + pm1, pm2 := bits.Mul64(xm<<10, ym<<11) + zm1, zm2 := zm<<10, uint64(0) + ps := xs ^ ys // product sign + + // normalize to 62nd bit + is62zero := uint((^pm1 >> 62) & 1) + pm1, pm2 = shl(pm1, pm2, is62zero) + pe -= int32(is62zero) + + // Swap addition operands so |p| >= |z| + if pe < ze || pe == ze && pm1 < zm1 { + ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2 + } + + // Align significands + zm1, zm2 = shrcompress(zm1, zm2, uint(pe-ze)) + + // Compute resulting significands, normalizing if necessary. + var m, c uint64 + if ps == zs { + // Adding (pm1:pm2) + (zm1:zm2) + pm2, c = bits.Add64(pm2, zm2, 0) + pm1, _ = bits.Add64(pm1, zm1, c) + pe -= int32(^pm1 >> 63) + pm1, m = shrcompress(pm1, pm2, uint(64+pm1>>63)) + } else { + // Subtracting (pm1:pm2) - (zm1:zm2) + // TODO: should we special-case cancellation? + pm2, c = bits.Sub64(pm2, zm2, 0) + pm1, _ = bits.Sub64(pm1, zm1, c) + nz := lz(pm1, pm2) + pe -= nz + m, pm2 = shl(pm1, pm2, uint(nz-1)) + m |= nonzero(pm2) + } + + // Round and break ties to even + if pe > 1022+bias || pe == 1022+bias && (m+1<<9)>>63 == 1 { + // rounded value overflows exponent range + return Float64frombits(uint64(ps)<<63 | uvinf) + } + if pe < 0 { + n := uint(-pe) + m = m>>n | nonzero(m&(1<<n-1)) + pe = 0 + } + m = ((m + 1<<9) >> 10) & ^zero((m&(1<<10-1))^1<<9) + pe &= -int32(nonzero(m)) + return Float64frombits(uint64(ps)<<63 + uint64(pe)<<52 + m) +} diff --git a/contrib/go/_std_1.18/src/math/frexp.go b/contrib/go/_std_1.18/src/math/frexp.go new file mode 100644 index 0000000000..3c8a909ed0 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/frexp.go @@ -0,0 +1,38 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Frexp breaks f into a normalized fraction +// and an integral power of two. +// It returns frac and exp satisfying f == frac × 2**exp, +// with the absolute value of frac in the interval [½, 1). +// +// Special cases are: +// Frexp(±0) = ±0, 0 +// Frexp(±Inf) = ±Inf, 0 +// Frexp(NaN) = NaN, 0 +func Frexp(f float64) (frac float64, exp int) { + if haveArchFrexp { + return archFrexp(f) + } + return frexp(f) +} + +func frexp(f float64) (frac float64, exp int) { + // special cases + switch { + case f == 0: + return f, 0 // correctly return -0 + case IsInf(f, 0) || IsNaN(f): + return f, 0 + } + f, exp = normalize(f) + x := Float64bits(f) + exp += int((x>>shift)&mask) - bias + 1 + x &^= mask << shift + x |= (-1 + bias) << shift + frac = Float64frombits(x) + return +} diff --git a/contrib/go/_std_1.18/src/math/gamma.go b/contrib/go/_std_1.18/src/math/gamma.go new file mode 100644 index 0000000000..cc9e869496 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/gamma.go @@ -0,0 +1,221 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below are from http://netlib.sandia.gov/cephes/cprob/gamma.c. +// The go code is a simplified version of the original C. +// +// tgamma.c +// +// Gamma function +// +// SYNOPSIS: +// +// double x, y, tgamma(); +// extern int signgam; +// +// y = tgamma( x ); +// +// DESCRIPTION: +// +// Returns gamma function of the argument. The result is +// correctly signed, and the sign (+1 or -1) is also +// returned in a global (extern) variable named signgam. +// This variable is also filled in by the logarithmic gamma +// function lgamma(). +// +// Arguments |x| <= 34 are reduced by recurrence and the function +// approximated by a rational function of degree 6/7 in the +// interval (2,3). Large arguments are handled by Stirling's +// formula. Large negative arguments are made positive using +// a reflection formula. +// +// ACCURACY: +// +// Relative error: +// arithmetic domain # trials peak rms +// DEC -34, 34 10000 1.3e-16 2.5e-17 +// IEEE -170,-33 20000 2.3e-15 3.3e-16 +// IEEE -33, 33 20000 9.4e-16 2.2e-16 +// IEEE 33, 171.6 20000 2.3e-15 3.2e-16 +// +// Error for arguments outside the test range will be larger +// owing to error amplification by the exponential function. +// +// Cephes Math Library Release 2.8: June, 2000 +// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier +// +// The readme file at http://netlib.sandia.gov/cephes/ says: +// Some software in this archive may be from the book _Methods and +// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +// International, 1989) or from the Cephes Mathematical Library, a +// commercial product. In either event, it is copyrighted by the author. +// What you see here may be used freely but it comes with no support or +// guarantee. +// +// The two known misprints in the book are repaired here in the +// source listings for the gamma function and the incomplete beta +// integral. +// +// Stephen L. Moshier +// moshier@na-net.ornl.gov + +var _gamP = [...]float64{ + 1.60119522476751861407e-04, + 1.19135147006586384913e-03, + 1.04213797561761569935e-02, + 4.76367800457137231464e-02, + 2.07448227648435975150e-01, + 4.94214826801497100753e-01, + 9.99999999999999996796e-01, +} +var _gamQ = [...]float64{ + -2.31581873324120129819e-05, + 5.39605580493303397842e-04, + -4.45641913851797240494e-03, + 1.18139785222060435552e-02, + 3.58236398605498653373e-02, + -2.34591795718243348568e-01, + 7.14304917030273074085e-02, + 1.00000000000000000320e+00, +} +var _gamS = [...]float64{ + 7.87311395793093628397e-04, + -2.29549961613378126380e-04, + -2.68132617805781232825e-03, + 3.47222221605458667310e-03, + 8.33333333333482257126e-02, +} + +// Gamma function computed by Stirling's formula. +// The pair of results must be multiplied together to get the actual answer. +// The multiplication is left to the caller so that, if careful, the caller can avoid +// infinity for 172 <= x <= 180. +// The polynomial is valid for 33 <= x <= 172; larger values are only used +// in reciprocal and produce denormalized floats. The lower precision there +// masks any imprecision in the polynomial. +func stirling(x float64) (float64, float64) { + if x > 200 { + return Inf(1), 1 + } + const ( + SqrtTwoPi = 2.506628274631000502417 + MaxStirling = 143.01608 + ) + w := 1 / x + w = 1 + w*((((_gamS[0]*w+_gamS[1])*w+_gamS[2])*w+_gamS[3])*w+_gamS[4]) + y1 := Exp(x) + y2 := 1.0 + if x > MaxStirling { // avoid Pow() overflow + v := Pow(x, 0.5*x-0.25) + y1, y2 = v, v/y1 + } else { + y1 = Pow(x, x-0.5) / y1 + } + return y1, SqrtTwoPi * w * y2 +} + +// Gamma returns the Gamma function of x. +// +// Special cases are: +// Gamma(+Inf) = +Inf +// Gamma(+0) = +Inf +// Gamma(-0) = -Inf +// Gamma(x) = NaN for integer x < 0 +// Gamma(-Inf) = NaN +// Gamma(NaN) = NaN +func Gamma(x float64) float64 { + const Euler = 0.57721566490153286060651209008240243104215933593992 // A001620 + // special cases + switch { + case isNegInt(x) || IsInf(x, -1) || IsNaN(x): + return NaN() + case IsInf(x, 1): + return Inf(1) + case x == 0: + if Signbit(x) { + return Inf(-1) + } + return Inf(1) + } + q := Abs(x) + p := Floor(q) + if q > 33 { + if x >= 0 { + y1, y2 := stirling(x) + return y1 * y2 + } + // Note: x is negative but (checked above) not a negative integer, + // so x must be small enough to be in range for conversion to int64. + // If |x| were >= 2⁶³ it would have to be an integer. + signgam := 1 + if ip := int64(p); ip&1 == 0 { + signgam = -1 + } + z := q - p + if z > 0.5 { + p = p + 1 + z = q - p + } + z = q * Sin(Pi*z) + if z == 0 { + return Inf(signgam) + } + sq1, sq2 := stirling(q) + absz := Abs(z) + d := absz * sq1 * sq2 + if IsInf(d, 0) { + z = Pi / absz / sq1 / sq2 + } else { + z = Pi / d + } + return float64(signgam) * z + } + + // Reduce argument + z := 1.0 + for x >= 3 { + x = x - 1 + z = z * x + } + for x < 0 { + if x > -1e-09 { + goto small + } + z = z / x + x = x + 1 + } + for x < 2 { + if x < 1e-09 { + goto small + } + z = z / x + x = x + 1 + } + + if x == 2 { + return z + } + + x = x - 2 + p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6] + q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7] + return z * p / q + +small: + if x == 0 { + return Inf(1) + } + return z / ((1 + Euler*x) * x) +} + +func isNegInt(x float64) bool { + if x < 0 { + _, xf := Modf(x) + return xf == 0 + } + return false +} diff --git a/contrib/go/_std_1.18/src/math/hypot.go b/contrib/go/_std_1.18/src/math/hypot.go new file mode 100644 index 0000000000..12af17766d --- /dev/null +++ b/contrib/go/_std_1.18/src/math/hypot.go @@ -0,0 +1,43 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Hypot -- sqrt(p*p + q*q), but overflows only if the result does. +*/ + +// Hypot returns Sqrt(p*p + q*q), taking care to avoid +// unnecessary overflow and underflow. +// +// Special cases are: +// Hypot(±Inf, q) = +Inf +// Hypot(p, ±Inf) = +Inf +// Hypot(NaN, q) = NaN +// Hypot(p, NaN) = NaN +func Hypot(p, q float64) float64 { + if haveArchHypot { + return archHypot(p, q) + } + return hypot(p, q) +} + +func hypot(p, q float64) float64 { + // special cases + switch { + case IsInf(p, 0) || IsInf(q, 0): + return Inf(1) + case IsNaN(p) || IsNaN(q): + return NaN() + } + p, q = Abs(p), Abs(q) + if p < q { + p, q = q, p + } + if p == 0 { + return 0 + } + q = q / p + return p * Sqrt(1+q*q) +} diff --git a/contrib/go/_std_1.18/src/math/hypot_amd64.s b/contrib/go/_std_1.18/src/math/hypot_amd64.s new file mode 100644 index 0000000000..fe326c9281 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/hypot_amd64.s @@ -0,0 +1,52 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +#define PosInf 0x7FF0000000000000 +#define NaN 0x7FF8000000000001 + +// func archHypot(p, q float64) float64 +TEXT ·archHypot(SB),NOSPLIT,$0 + // test bits for special cases + MOVQ p+0(FP), BX + MOVQ $~(1<<63), AX + ANDQ AX, BX // p = |p| + MOVQ q+8(FP), CX + ANDQ AX, CX // q = |q| + MOVQ $PosInf, AX + CMPQ AX, BX + JLE isInfOrNaN + CMPQ AX, CX + JLE isInfOrNaN + // hypot = max * sqrt(1 + (min/max)**2) + MOVQ BX, X0 + MOVQ CX, X1 + ORQ CX, BX + JEQ isZero + MOVAPD X0, X2 + MAXSD X1, X0 + MINSD X2, X1 + DIVSD X0, X1 + MULSD X1, X1 + ADDSD $1.0, X1 + SQRTSD X1, X1 + MULSD X1, X0 + MOVSD X0, ret+16(FP) + RET +isInfOrNaN: + CMPQ AX, BX + JEQ isInf + CMPQ AX, CX + JEQ isInf + MOVQ $NaN, AX + MOVQ AX, ret+16(FP) // return NaN + RET +isInf: + MOVQ AX, ret+16(FP) // return +Inf + RET +isZero: + MOVQ $0, AX + MOVQ AX, ret+16(FP) // return 0 + RET diff --git a/contrib/go/_std_1.18/src/math/hypot_asm.go b/contrib/go/_std_1.18/src/math/hypot_asm.go new file mode 100644 index 0000000000..852691037f --- /dev/null +++ b/contrib/go/_std_1.18/src/math/hypot_asm.go @@ -0,0 +1,11 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build 386 || amd64 + +package math + +const haveArchHypot = true + +func archHypot(p, q float64) float64 diff --git a/contrib/go/_std_1.18/src/math/j0.go b/contrib/go/_std_1.18/src/math/j0.go new file mode 100644 index 0000000000..cb5f07bca6 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/j0.go @@ -0,0 +1,427 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Bessel function of the first and second kinds of order zero. +*/ + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/e_j0.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_j0(x), __ieee754_y0(x) +// Bessel function of the first and second kinds of order zero. +// Method -- j0(x): +// 1. For tiny x, we use j0(x) = 1 - x**2/4 + x**4/64 - ... +// 2. Reduce x to |x| since j0(x)=j0(-x), and +// for x in (0,2) +// j0(x) = 1-z/4+ z**2*R0/S0, where z = x*x; +// (precision: |j0-1+z/4-z**2R0/S0 |<2**-63.67 ) +// for x in (2,inf) +// j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) +// where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) +// as follow: +// cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) +// = 1/sqrt(2) * (cos(x) + sin(x)) +// sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) +// = 1/sqrt(2) * (sin(x) - cos(x)) +// (To avoid cancellation, use +// sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) +// to compute the worse one.) +// +// 3 Special cases +// j0(nan)= nan +// j0(0) = 1 +// j0(inf) = 0 +// +// Method -- y0(x): +// 1. For x<2. +// Since +// y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x**2/4 - ...) +// therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. +// We use the following function to approximate y0, +// y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x**2 +// where +// U(z) = u00 + u01*z + ... + u06*z**6 +// V(z) = 1 + v01*z + ... + v04*z**4 +// with absolute approximation error bounded by 2**-72. +// Note: For tiny x, U/V = u0 and j0(x)~1, hence +// y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) +// 2. For x>=2. +// y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) +// where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) +// by the method mentioned above. +// 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. +// + +// J0 returns the order-zero Bessel function of the first kind. +// +// Special cases are: +// J0(±Inf) = 0 +// J0(0) = 1 +// J0(NaN) = NaN +func J0(x float64) float64 { + const ( + Huge = 1e300 + TwoM27 = 1.0 / (1 << 27) // 2**-27 0x3e40000000000000 + TwoM13 = 1.0 / (1 << 13) // 2**-13 0x3f20000000000000 + Two129 = 1 << 129 // 2**129 0x4800000000000000 + // R0/S0 on [0, 2] + R02 = 1.56249999999999947958e-02 // 0x3F8FFFFFFFFFFFFD + R03 = -1.89979294238854721751e-04 // 0xBF28E6A5B61AC6E9 + R04 = 1.82954049532700665670e-06 // 0x3EBEB1D10C503919 + R05 = -4.61832688532103189199e-09 // 0xBE33D5E773D63FCE + S01 = 1.56191029464890010492e-02 // 0x3F8FFCE882C8C2A4 + S02 = 1.16926784663337450260e-04 // 0x3F1EA6D2DD57DBF4 + S03 = 5.13546550207318111446e-07 // 0x3EA13B54CE84D5A9 + S04 = 1.16614003333790000205e-09 // 0x3E1408BCF4745D8F + ) + // special cases + switch { + case IsNaN(x): + return x + case IsInf(x, 0): + return 0 + case x == 0: + return 1 + } + + x = Abs(x) + if x >= 2 { + s, c := Sincos(x) + ss := s - c + cc := s + c + + // make sure x+x does not overflow + if x < MaxFloat64/2 { + z := -Cos(x + x) + if s*c < 0 { + cc = z / ss + } else { + ss = z / cc + } + } + + // j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + // y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + + var z float64 + if x > Two129 { // |x| > ~6.8056e+38 + z = (1 / SqrtPi) * cc / Sqrt(x) + } else { + u := pzero(x) + v := qzero(x) + z = (1 / SqrtPi) * (u*cc - v*ss) / Sqrt(x) + } + return z // |x| >= 2.0 + } + if x < TwoM13 { // |x| < ~1.2207e-4 + if x < TwoM27 { + return 1 // |x| < ~7.4506e-9 + } + return 1 - 0.25*x*x // ~7.4506e-9 < |x| < ~1.2207e-4 + } + z := x * x + r := z * (R02 + z*(R03+z*(R04+z*R05))) + s := 1 + z*(S01+z*(S02+z*(S03+z*S04))) + if x < 1 { + return 1 + z*(-0.25+(r/s)) // |x| < 1.00 + } + u := 0.5 * x + return (1+u)*(1-u) + z*(r/s) // 1.0 < |x| < 2.0 +} + +// Y0 returns the order-zero Bessel function of the second kind. +// +// Special cases are: +// Y0(+Inf) = 0 +// Y0(0) = -Inf +// Y0(x < 0) = NaN +// Y0(NaN) = NaN +func Y0(x float64) float64 { + const ( + TwoM27 = 1.0 / (1 << 27) // 2**-27 0x3e40000000000000 + Two129 = 1 << 129 // 2**129 0x4800000000000000 + U00 = -7.38042951086872317523e-02 // 0xBFB2E4D699CBD01F + U01 = 1.76666452509181115538e-01 // 0x3FC69D019DE9E3FC + U02 = -1.38185671945596898896e-02 // 0xBF8C4CE8B16CFA97 + U03 = 3.47453432093683650238e-04 // 0x3F36C54D20B29B6B + U04 = -3.81407053724364161125e-06 // 0xBECFFEA773D25CAD + U05 = 1.95590137035022920206e-08 // 0x3E5500573B4EABD4 + U06 = -3.98205194132103398453e-11 // 0xBDC5E43D693FB3C8 + V01 = 1.27304834834123699328e-02 // 0x3F8A127091C9C71A + V02 = 7.60068627350353253702e-05 // 0x3F13ECBBF578C6C1 + V03 = 2.59150851840457805467e-07 // 0x3E91642D7FF202FD + V04 = 4.41110311332675467403e-10 // 0x3DFE50183BD6D9EF + ) + // special cases + switch { + case x < 0 || IsNaN(x): + return NaN() + case IsInf(x, 1): + return 0 + case x == 0: + return Inf(-1) + } + + if x >= 2 { // |x| >= 2.0 + + // y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + // where x0 = x-pi/4 + // Better formula: + // cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + // = 1/sqrt(2) * (sin(x) + cos(x)) + // sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + // = 1/sqrt(2) * (sin(x) - cos(x)) + // To avoid cancellation, use + // sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + // to compute the worse one. + + s, c := Sincos(x) + ss := s - c + cc := s + c + + // j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + // y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + + // make sure x+x does not overflow + if x < MaxFloat64/2 { + z := -Cos(x + x) + if s*c < 0 { + cc = z / ss + } else { + ss = z / cc + } + } + var z float64 + if x > Two129 { // |x| > ~6.8056e+38 + z = (1 / SqrtPi) * ss / Sqrt(x) + } else { + u := pzero(x) + v := qzero(x) + z = (1 / SqrtPi) * (u*ss + v*cc) / Sqrt(x) + } + return z // |x| >= 2.0 + } + if x <= TwoM27 { + return U00 + (2/Pi)*Log(x) // |x| < ~7.4506e-9 + } + z := x * x + u := U00 + z*(U01+z*(U02+z*(U03+z*(U04+z*(U05+z*U06))))) + v := 1 + z*(V01+z*(V02+z*(V03+z*V04))) + return u/v + (2/Pi)*J0(x)*Log(x) // ~7.4506e-9 < |x| < 2.0 +} + +// The asymptotic expansions of pzero is +// 1 - 9/128 s**2 + 11025/98304 s**4 - ..., where s = 1/x. +// For x >= 2, We approximate pzero by +// pzero(x) = 1 + (R/S) +// where R = pR0 + pR1*s**2 + pR2*s**4 + ... + pR5*s**10 +// S = 1 + pS0*s**2 + ... + pS4*s**10 +// and +// | pzero(x)-1-R/S | <= 2 ** ( -60.26) + +// for x in [inf, 8]=1/[0,0.125] +var p0R8 = [6]float64{ + 0.00000000000000000000e+00, // 0x0000000000000000 + -7.03124999999900357484e-02, // 0xBFB1FFFFFFFFFD32 + -8.08167041275349795626e+00, // 0xC02029D0B44FA779 + -2.57063105679704847262e+02, // 0xC07011027B19E863 + -2.48521641009428822144e+03, // 0xC0A36A6ECD4DCAFC + -5.25304380490729545272e+03, // 0xC0B4850B36CC643D +} +var p0S8 = [5]float64{ + 1.16534364619668181717e+02, // 0x405D223307A96751 + 3.83374475364121826715e+03, // 0x40ADF37D50596938 + 4.05978572648472545552e+04, // 0x40E3D2BB6EB6B05F + 1.16752972564375915681e+05, // 0x40FC810F8F9FA9BD + 4.76277284146730962675e+04, // 0x40E741774F2C49DC +} + +// for x in [8,4.5454]=1/[0.125,0.22001] +var p0R5 = [6]float64{ + -1.14125464691894502584e-11, // 0xBDA918B147E495CC + -7.03124940873599280078e-02, // 0xBFB1FFFFE69AFBC6 + -4.15961064470587782438e+00, // 0xC010A370F90C6BBF + -6.76747652265167261021e+01, // 0xC050EB2F5A7D1783 + -3.31231299649172967747e+02, // 0xC074B3B36742CC63 + -3.46433388365604912451e+02, // 0xC075A6EF28A38BD7 +} +var p0S5 = [5]float64{ + 6.07539382692300335975e+01, // 0x404E60810C98C5DE + 1.05125230595704579173e+03, // 0x40906D025C7E2864 + 5.97897094333855784498e+03, // 0x40B75AF88FBE1D60 + 9.62544514357774460223e+03, // 0x40C2CCB8FA76FA38 + 2.40605815922939109441e+03, // 0x40A2CC1DC70BE864 +} + +// for x in [4.547,2.8571]=1/[0.2199,0.35001] +var p0R3 = [6]float64{ + -2.54704601771951915620e-09, // 0xBE25E1036FE1AA86 + -7.03119616381481654654e-02, // 0xBFB1FFF6F7C0E24B + -2.40903221549529611423e+00, // 0xC00345B2AEA48074 + -2.19659774734883086467e+01, // 0xC035F74A4CB94E14 + -5.80791704701737572236e+01, // 0xC04D0A22420A1A45 + -3.14479470594888503854e+01, // 0xC03F72ACA892D80F +} +var p0S3 = [5]float64{ + 3.58560338055209726349e+01, // 0x4041ED9284077DD3 + 3.61513983050303863820e+02, // 0x40769839464A7C0E + 1.19360783792111533330e+03, // 0x4092A66E6D1061D6 + 1.12799679856907414432e+03, // 0x40919FFCB8C39B7E + 1.73580930813335754692e+02, // 0x4065B296FC379081 +} + +// for x in [2.8570,2]=1/[0.3499,0.5] +var p0R2 = [6]float64{ + -8.87534333032526411254e-08, // 0xBE77D316E927026D + -7.03030995483624743247e-02, // 0xBFB1FF62495E1E42 + -1.45073846780952986357e+00, // 0xBFF736398A24A843 + -7.63569613823527770791e+00, // 0xC01E8AF3EDAFA7F3 + -1.11931668860356747786e+01, // 0xC02662E6C5246303 + -3.23364579351335335033e+00, // 0xC009DE81AF8FE70F +} +var p0S2 = [5]float64{ + 2.22202997532088808441e+01, // 0x40363865908B5959 + 1.36206794218215208048e+02, // 0x4061069E0EE8878F + 2.70470278658083486789e+02, // 0x4070E78642EA079B + 1.53875394208320329881e+02, // 0x40633C033AB6FAFF + 1.46576176948256193810e+01, // 0x402D50B344391809 +} + +func pzero(x float64) float64 { + var p *[6]float64 + var q *[5]float64 + if x >= 8 { + p = &p0R8 + q = &p0S8 + } else if x >= 4.5454 { + p = &p0R5 + q = &p0S5 + } else if x >= 2.8571 { + p = &p0R3 + q = &p0S3 + } else if x >= 2 { + p = &p0R2 + q = &p0S2 + } + z := 1 / (x * x) + r := p[0] + z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))) + s := 1 + z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))) + return 1 + r/s +} + +// For x >= 8, the asymptotic expansions of qzero is +// -1/8 s + 75/1024 s**3 - ..., where s = 1/x. +// We approximate pzero by +// qzero(x) = s*(-1.25 + (R/S)) +// where R = qR0 + qR1*s**2 + qR2*s**4 + ... + qR5*s**10 +// S = 1 + qS0*s**2 + ... + qS5*s**12 +// and +// | qzero(x)/s +1.25-R/S | <= 2**(-61.22) + +// for x in [inf, 8]=1/[0,0.125] +var q0R8 = [6]float64{ + 0.00000000000000000000e+00, // 0x0000000000000000 + 7.32421874999935051953e-02, // 0x3FB2BFFFFFFFFE2C + 1.17682064682252693899e+01, // 0x402789525BB334D6 + 5.57673380256401856059e+02, // 0x40816D6315301825 + 8.85919720756468632317e+03, // 0x40C14D993E18F46D + 3.70146267776887834771e+04, // 0x40E212D40E901566 +} +var q0S8 = [6]float64{ + 1.63776026895689824414e+02, // 0x406478D5365B39BC + 8.09834494656449805916e+03, // 0x40BFA2584E6B0563 + 1.42538291419120476348e+05, // 0x4101665254D38C3F + 8.03309257119514397345e+05, // 0x412883DA83A52B43 + 8.40501579819060512818e+05, // 0x4129A66B28DE0B3D + -3.43899293537866615225e+05, // 0xC114FD6D2C9530C5 +} + +// for x in [8,4.5454]=1/[0.125,0.22001] +var q0R5 = [6]float64{ + 1.84085963594515531381e-11, // 0x3DB43D8F29CC8CD9 + 7.32421766612684765896e-02, // 0x3FB2BFFFD172B04C + 5.83563508962056953777e+00, // 0x401757B0B9953DD3 + 1.35111577286449829671e+02, // 0x4060E3920A8788E9 + 1.02724376596164097464e+03, // 0x40900CF99DC8C481 + 1.98997785864605384631e+03, // 0x409F17E953C6E3A6 +} +var q0S5 = [6]float64{ + 8.27766102236537761883e+01, // 0x4054B1B3FB5E1543 + 2.07781416421392987104e+03, // 0x40A03BA0DA21C0CE + 1.88472887785718085070e+04, // 0x40D267D27B591E6D + 5.67511122894947329769e+04, // 0x40EBB5E397E02372 + 3.59767538425114471465e+04, // 0x40E191181F7A54A0 + -5.35434275601944773371e+03, // 0xC0B4EA57BEDBC609 +} + +// for x in [4.547,2.8571]=1/[0.2199,0.35001] +var q0R3 = [6]float64{ + 4.37741014089738620906e-09, // 0x3E32CD036ADECB82 + 7.32411180042911447163e-02, // 0x3FB2BFEE0E8D0842 + 3.34423137516170720929e+00, // 0x400AC0FC61149CF5 + 4.26218440745412650017e+01, // 0x40454F98962DAEDD + 1.70808091340565596283e+02, // 0x406559DBE25EFD1F + 1.66733948696651168575e+02, // 0x4064D77C81FA21E0 +} +var q0S3 = [6]float64{ + 4.87588729724587182091e+01, // 0x40486122BFE343A6 + 7.09689221056606015736e+02, // 0x40862D8386544EB3 + 3.70414822620111362994e+03, // 0x40ACF04BE44DFC63 + 6.46042516752568917582e+03, // 0x40B93C6CD7C76A28 + 2.51633368920368957333e+03, // 0x40A3A8AAD94FB1C0 + -1.49247451836156386662e+02, // 0xC062A7EB201CF40F +} + +// for x in [2.8570,2]=1/[0.3499,0.5] +var q0R2 = [6]float64{ + 1.50444444886983272379e-07, // 0x3E84313B54F76BDB + 7.32234265963079278272e-02, // 0x3FB2BEC53E883E34 + 1.99819174093815998816e+00, // 0x3FFFF897E727779C + 1.44956029347885735348e+01, // 0x402CFDBFAAF96FE5 + 3.16662317504781540833e+01, // 0x403FAA8E29FBDC4A + 1.62527075710929267416e+01, // 0x403040B171814BB4 +} +var q0S2 = [6]float64{ + 3.03655848355219184498e+01, // 0x403E5D96F7C07AED + 2.69348118608049844624e+02, // 0x4070D591E4D14B40 + 8.44783757595320139444e+02, // 0x408A664522B3BF22 + 8.82935845112488550512e+02, // 0x408B977C9C5CC214 + 2.12666388511798828631e+02, // 0x406A95530E001365 + -5.31095493882666946917e+00, // 0xC0153E6AF8B32931 +} + +func qzero(x float64) float64 { + var p, q *[6]float64 + if x >= 8 { + p = &q0R8 + q = &q0S8 + } else if x >= 4.5454 { + p = &q0R5 + q = &q0S5 + } else if x >= 2.8571 { + p = &q0R3 + q = &q0S3 + } else if x >= 2 { + p = &q0R2 + q = &q0S2 + } + z := 1 / (x * x) + r := p[0] + z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))) + s := 1 + z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))) + return (-0.125 + r/s) / x +} diff --git a/contrib/go/_std_1.18/src/math/j1.go b/contrib/go/_std_1.18/src/math/j1.go new file mode 100644 index 0000000000..7c7d279730 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/j1.go @@ -0,0 +1,422 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Bessel function of the first and second kinds of order one. +*/ + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/e_j1.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_j1(x), __ieee754_y1(x) +// Bessel function of the first and second kinds of order one. +// Method -- j1(x): +// 1. For tiny x, we use j1(x) = x/2 - x**3/16 + x**5/384 - ... +// 2. Reduce x to |x| since j1(x)=-j1(-x), and +// for x in (0,2) +// j1(x) = x/2 + x*z*R0/S0, where z = x*x; +// (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 ) +// for x in (2,inf) +// j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) +// y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) +// where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) +// as follow: +// cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) +// = 1/sqrt(2) * (sin(x) - cos(x)) +// sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) +// = -1/sqrt(2) * (sin(x) + cos(x)) +// (To avoid cancellation, use +// sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) +// to compute the worse one.) +// +// 3 Special cases +// j1(nan)= nan +// j1(0) = 0 +// j1(inf) = 0 +// +// Method -- y1(x): +// 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN +// 2. For x<2. +// Since +// y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x**3-...) +// therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. +// We use the following function to approximate y1, +// y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x**2 +// where for x in [0,2] (abs err less than 2**-65.89) +// U(z) = U0[0] + U0[1]*z + ... + U0[4]*z**4 +// V(z) = 1 + v0[0]*z + ... + v0[4]*z**5 +// Note: For tiny x, 1/x dominate y1 and hence +// y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) +// 3. For x>=2. +// y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) +// where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) +// by method mentioned above. + +// J1 returns the order-one Bessel function of the first kind. +// +// Special cases are: +// J1(±Inf) = 0 +// J1(NaN) = NaN +func J1(x float64) float64 { + const ( + TwoM27 = 1.0 / (1 << 27) // 2**-27 0x3e40000000000000 + Two129 = 1 << 129 // 2**129 0x4800000000000000 + // R0/S0 on [0, 2] + R00 = -6.25000000000000000000e-02 // 0xBFB0000000000000 + R01 = 1.40705666955189706048e-03 // 0x3F570D9F98472C61 + R02 = -1.59955631084035597520e-05 // 0xBEF0C5C6BA169668 + R03 = 4.96727999609584448412e-08 // 0x3E6AAAFA46CA0BD9 + S01 = 1.91537599538363460805e-02 // 0x3F939D0B12637E53 + S02 = 1.85946785588630915560e-04 // 0x3F285F56B9CDF664 + S03 = 1.17718464042623683263e-06 // 0x3EB3BFF8333F8498 + S04 = 5.04636257076217042715e-09 // 0x3E35AC88C97DFF2C + S05 = 1.23542274426137913908e-11 // 0x3DAB2ACFCFB97ED8 + ) + // special cases + switch { + case IsNaN(x): + return x + case IsInf(x, 0) || x == 0: + return 0 + } + + sign := false + if x < 0 { + x = -x + sign = true + } + if x >= 2 { + s, c := Sincos(x) + ss := -s - c + cc := s - c + + // make sure x+x does not overflow + if x < MaxFloat64/2 { + z := Cos(x + x) + if s*c > 0 { + cc = z / ss + } else { + ss = z / cc + } + } + + // j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + // y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + + var z float64 + if x > Two129 { + z = (1 / SqrtPi) * cc / Sqrt(x) + } else { + u := pone(x) + v := qone(x) + z = (1 / SqrtPi) * (u*cc - v*ss) / Sqrt(x) + } + if sign { + return -z + } + return z + } + if x < TwoM27 { // |x|<2**-27 + return 0.5 * x // inexact if x!=0 necessary + } + z := x * x + r := z * (R00 + z*(R01+z*(R02+z*R03))) + s := 1.0 + z*(S01+z*(S02+z*(S03+z*(S04+z*S05)))) + r *= x + z = 0.5*x + r/s + if sign { + return -z + } + return z +} + +// Y1 returns the order-one Bessel function of the second kind. +// +// Special cases are: +// Y1(+Inf) = 0 +// Y1(0) = -Inf +// Y1(x < 0) = NaN +// Y1(NaN) = NaN +func Y1(x float64) float64 { + const ( + TwoM54 = 1.0 / (1 << 54) // 2**-54 0x3c90000000000000 + Two129 = 1 << 129 // 2**129 0x4800000000000000 + U00 = -1.96057090646238940668e-01 // 0xBFC91866143CBC8A + U01 = 5.04438716639811282616e-02 // 0x3FA9D3C776292CD1 + U02 = -1.91256895875763547298e-03 // 0xBF5F55E54844F50F + U03 = 2.35252600561610495928e-05 // 0x3EF8AB038FA6B88E + U04 = -9.19099158039878874504e-08 // 0xBE78AC00569105B8 + V00 = 1.99167318236649903973e-02 // 0x3F94650D3F4DA9F0 + V01 = 2.02552581025135171496e-04 // 0x3F2A8C896C257764 + V02 = 1.35608801097516229404e-06 // 0x3EB6C05A894E8CA6 + V03 = 6.22741452364621501295e-09 // 0x3E3ABF1D5BA69A86 + V04 = 1.66559246207992079114e-11 // 0x3DB25039DACA772A + ) + // special cases + switch { + case x < 0 || IsNaN(x): + return NaN() + case IsInf(x, 1): + return 0 + case x == 0: + return Inf(-1) + } + + if x >= 2 { + s, c := Sincos(x) + ss := -s - c + cc := s - c + + // make sure x+x does not overflow + if x < MaxFloat64/2 { + z := Cos(x + x) + if s*c > 0 { + cc = z / ss + } else { + ss = z / cc + } + } + // y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + // where x0 = x-3pi/4 + // Better formula: + // cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + // = 1/sqrt(2) * (sin(x) - cos(x)) + // sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + // = -1/sqrt(2) * (cos(x) + sin(x)) + // To avoid cancellation, use + // sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + // to compute the worse one. + + var z float64 + if x > Two129 { + z = (1 / SqrtPi) * ss / Sqrt(x) + } else { + u := pone(x) + v := qone(x) + z = (1 / SqrtPi) * (u*ss + v*cc) / Sqrt(x) + } + return z + } + if x <= TwoM54 { // x < 2**-54 + return -(2 / Pi) / x + } + z := x * x + u := U00 + z*(U01+z*(U02+z*(U03+z*U04))) + v := 1 + z*(V00+z*(V01+z*(V02+z*(V03+z*V04)))) + return x*(u/v) + (2/Pi)*(J1(x)*Log(x)-1/x) +} + +// For x >= 8, the asymptotic expansions of pone is +// 1 + 15/128 s**2 - 4725/2**15 s**4 - ..., where s = 1/x. +// We approximate pone by +// pone(x) = 1 + (R/S) +// where R = pr0 + pr1*s**2 + pr2*s**4 + ... + pr5*s**10 +// S = 1 + ps0*s**2 + ... + ps4*s**10 +// and +// | pone(x)-1-R/S | <= 2**(-60.06) + +// for x in [inf, 8]=1/[0,0.125] +var p1R8 = [6]float64{ + 0.00000000000000000000e+00, // 0x0000000000000000 + 1.17187499999988647970e-01, // 0x3FBDFFFFFFFFFCCE + 1.32394806593073575129e+01, // 0x402A7A9D357F7FCE + 4.12051854307378562225e+02, // 0x4079C0D4652EA590 + 3.87474538913960532227e+03, // 0x40AE457DA3A532CC + 7.91447954031891731574e+03, // 0x40BEEA7AC32782DD +} +var p1S8 = [5]float64{ + 1.14207370375678408436e+02, // 0x405C8D458E656CAC + 3.65093083420853463394e+03, // 0x40AC85DC964D274F + 3.69562060269033463555e+04, // 0x40E20B8697C5BB7F + 9.76027935934950801311e+04, // 0x40F7D42CB28F17BB + 3.08042720627888811578e+04, // 0x40DE1511697A0B2D +} + +// for x in [8,4.5454] = 1/[0.125,0.22001] +var p1R5 = [6]float64{ + 1.31990519556243522749e-11, // 0x3DAD0667DAE1CA7D + 1.17187493190614097638e-01, // 0x3FBDFFFFE2C10043 + 6.80275127868432871736e+00, // 0x401B36046E6315E3 + 1.08308182990189109773e+02, // 0x405B13B9452602ED + 5.17636139533199752805e+02, // 0x40802D16D052D649 + 5.28715201363337541807e+02, // 0x408085B8BB7E0CB7 +} +var p1S5 = [5]float64{ + 5.92805987221131331921e+01, // 0x404DA3EAA8AF633D + 9.91401418733614377743e+02, // 0x408EFB361B066701 + 5.35326695291487976647e+03, // 0x40B4E9445706B6FB + 7.84469031749551231769e+03, // 0x40BEA4B0B8A5BB15 + 1.50404688810361062679e+03, // 0x40978030036F5E51 +} + +// for x in[4.5453,2.8571] = 1/[0.2199,0.35001] +var p1R3 = [6]float64{ + 3.02503916137373618024e-09, // 0x3E29FC21A7AD9EDD + 1.17186865567253592491e-01, // 0x3FBDFFF55B21D17B + 3.93297750033315640650e+00, // 0x400F76BCE85EAD8A + 3.51194035591636932736e+01, // 0x40418F489DA6D129 + 9.10550110750781271918e+01, // 0x4056C3854D2C1837 + 4.85590685197364919645e+01, // 0x4048478F8EA83EE5 +} +var p1S3 = [5]float64{ + 3.47913095001251519989e+01, // 0x40416549A134069C + 3.36762458747825746741e+02, // 0x40750C3307F1A75F + 1.04687139975775130551e+03, // 0x40905B7C5037D523 + 8.90811346398256432622e+02, // 0x408BD67DA32E31E9 + 1.03787932439639277504e+02, // 0x4059F26D7C2EED53 +} + +// for x in [2.8570,2] = 1/[0.3499,0.5] +var p1R2 = [6]float64{ + 1.07710830106873743082e-07, // 0x3E7CE9D4F65544F4 + 1.17176219462683348094e-01, // 0x3FBDFF42BE760D83 + 2.36851496667608785174e+00, // 0x4002F2B7F98FAEC0 + 1.22426109148261232917e+01, // 0x40287C377F71A964 + 1.76939711271687727390e+01, // 0x4031B1A8177F8EE2 + 5.07352312588818499250e+00, // 0x40144B49A574C1FE +} +var p1S2 = [5]float64{ + 2.14364859363821409488e+01, // 0x40356FBD8AD5ECDC + 1.25290227168402751090e+02, // 0x405F529314F92CD5 + 2.32276469057162813669e+02, // 0x406D08D8D5A2DBD9 + 1.17679373287147100768e+02, // 0x405D6B7ADA1884A9 + 8.36463893371618283368e+00, // 0x4020BAB1F44E5192 +} + +func pone(x float64) float64 { + var p *[6]float64 + var q *[5]float64 + if x >= 8 { + p = &p1R8 + q = &p1S8 + } else if x >= 4.5454 { + p = &p1R5 + q = &p1S5 + } else if x >= 2.8571 { + p = &p1R3 + q = &p1S3 + } else if x >= 2 { + p = &p1R2 + q = &p1S2 + } + z := 1 / (x * x) + r := p[0] + z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))) + s := 1.0 + z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))) + return 1 + r/s +} + +// For x >= 8, the asymptotic expansions of qone is +// 3/8 s - 105/1024 s**3 - ..., where s = 1/x. +// We approximate qone by +// qone(x) = s*(0.375 + (R/S)) +// where R = qr1*s**2 + qr2*s**4 + ... + qr5*s**10 +// S = 1 + qs1*s**2 + ... + qs6*s**12 +// and +// | qone(x)/s -0.375-R/S | <= 2**(-61.13) + +// for x in [inf, 8] = 1/[0,0.125] +var q1R8 = [6]float64{ + 0.00000000000000000000e+00, // 0x0000000000000000 + -1.02539062499992714161e-01, // 0xBFBA3FFFFFFFFDF3 + -1.62717534544589987888e+01, // 0xC0304591A26779F7 + -7.59601722513950107896e+02, // 0xC087BCD053E4B576 + -1.18498066702429587167e+04, // 0xC0C724E740F87415 + -4.84385124285750353010e+04, // 0xC0E7A6D065D09C6A +} +var q1S8 = [6]float64{ + 1.61395369700722909556e+02, // 0x40642CA6DE5BCDE5 + 7.82538599923348465381e+03, // 0x40BE9162D0D88419 + 1.33875336287249578163e+05, // 0x4100579AB0B75E98 + 7.19657723683240939863e+05, // 0x4125F65372869C19 + 6.66601232617776375264e+05, // 0x412457D27719AD5C + -2.94490264303834643215e+05, // 0xC111F9690EA5AA18 +} + +// for x in [8,4.5454] = 1/[0.125,0.22001] +var q1R5 = [6]float64{ + -2.08979931141764104297e-11, // 0xBDB6FA431AA1A098 + -1.02539050241375426231e-01, // 0xBFBA3FFFCB597FEF + -8.05644828123936029840e+00, // 0xC0201CE6CA03AD4B + -1.83669607474888380239e+02, // 0xC066F56D6CA7B9B0 + -1.37319376065508163265e+03, // 0xC09574C66931734F + -2.61244440453215656817e+03, // 0xC0A468E388FDA79D +} +var q1S5 = [6]float64{ + 8.12765501384335777857e+01, // 0x405451B2FF5A11B2 + 1.99179873460485964642e+03, // 0x409F1F31E77BF839 + 1.74684851924908907677e+04, // 0x40D10F1F0D64CE29 + 4.98514270910352279316e+04, // 0x40E8576DAABAD197 + 2.79480751638918118260e+04, // 0x40DB4B04CF7C364B + -4.71918354795128470869e+03, // 0xC0B26F2EFCFFA004 +} + +// for x in [4.5454,2.8571] = 1/[0.2199,0.35001] ??? +var q1R3 = [6]float64{ + -5.07831226461766561369e-09, // 0xBE35CFA9D38FC84F + -1.02537829820837089745e-01, // 0xBFBA3FEB51AEED54 + -4.61011581139473403113e+00, // 0xC01270C23302D9FF + -5.78472216562783643212e+01, // 0xC04CEC71C25D16DA + -2.28244540737631695038e+02, // 0xC06C87D34718D55F + -2.19210128478909325622e+02, // 0xC06B66B95F5C1BF6 +} +var q1S3 = [6]float64{ + 4.76651550323729509273e+01, // 0x4047D523CCD367E4 + 6.73865112676699709482e+02, // 0x40850EEBC031EE3E + 3.38015286679526343505e+03, // 0x40AA684E448E7C9A + 5.54772909720722782367e+03, // 0x40B5ABBAA61D54A6 + 1.90311919338810798763e+03, // 0x409DBC7A0DD4DF4B + -1.35201191444307340817e+02, // 0xC060E670290A311F +} + +// for x in [2.8570,2] = 1/[0.3499,0.5] +var q1R2 = [6]float64{ + -1.78381727510958865572e-07, // 0xBE87F12644C626D2 + -1.02517042607985553460e-01, // 0xBFBA3E8E9148B010 + -2.75220568278187460720e+00, // 0xC006048469BB4EDA + -1.96636162643703720221e+01, // 0xC033A9E2C168907F + -4.23253133372830490089e+01, // 0xC04529A3DE104AAA + -2.13719211703704061733e+01, // 0xC0355F3639CF6E52 +} +var q1S2 = [6]float64{ + 2.95333629060523854548e+01, // 0x403D888A78AE64FF + 2.52981549982190529136e+02, // 0x406F9F68DB821CBA + 7.57502834868645436472e+02, // 0x4087AC05CE49A0F7 + 7.39393205320467245656e+02, // 0x40871B2548D4C029 + 1.55949003336666123687e+02, // 0x40637E5E3C3ED8D4 + -4.95949898822628210127e+00, // 0xC013D686E71BE86B +} + +func qone(x float64) float64 { + var p, q *[6]float64 + if x >= 8 { + p = &q1R8 + q = &q1S8 + } else if x >= 4.5454 { + p = &q1R5 + q = &q1S5 + } else if x >= 2.8571 { + p = &q1R3 + q = &q1S3 + } else if x >= 2 { + p = &q1R2 + q = &q1S2 + } + z := 1 / (x * x) + r := p[0] + z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))) + s := 1 + z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))) + return (0.375 + r/s) / x +} diff --git a/contrib/go/_std_1.18/src/math/jn.go b/contrib/go/_std_1.18/src/math/jn.go new file mode 100644 index 0000000000..b1aca8ff6b --- /dev/null +++ b/contrib/go/_std_1.18/src/math/jn.go @@ -0,0 +1,304 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Bessel function of the first and second kinds of order n. +*/ + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/e_jn.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_jn(n, x), __ieee754_yn(n, x) +// floating point Bessel's function of the 1st and 2nd kind +// of order n +// +// Special cases: +// y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; +// y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. +// Note 2. About jn(n,x), yn(n,x) +// For n=0, j0(x) is called, +// for n=1, j1(x) is called, +// for n<x, forward recursion is used starting +// from values of j0(x) and j1(x). +// for n>x, a continued fraction approximation to +// j(n,x)/j(n-1,x) is evaluated and then backward +// recursion is used starting from a supposed value +// for j(n,x). The resulting value of j(0,x) is +// compared with the actual value to correct the +// supposed value of j(n,x). +// +// yn(n,x) is similar in all respects, except +// that forward recursion is used for all +// values of n>1. + +// Jn returns the order-n Bessel function of the first kind. +// +// Special cases are: +// Jn(n, ±Inf) = 0 +// Jn(n, NaN) = NaN +func Jn(n int, x float64) float64 { + const ( + TwoM29 = 1.0 / (1 << 29) // 2**-29 0x3e10000000000000 + Two302 = 1 << 302 // 2**302 0x52D0000000000000 + ) + // special cases + switch { + case IsNaN(x): + return x + case IsInf(x, 0): + return 0 + } + // J(-n, x) = (-1)**n * J(n, x), J(n, -x) = (-1)**n * J(n, x) + // Thus, J(-n, x) = J(n, -x) + + if n == 0 { + return J0(x) + } + if x == 0 { + return 0 + } + if n < 0 { + n, x = -n, -x + } + if n == 1 { + return J1(x) + } + sign := false + if x < 0 { + x = -x + if n&1 == 1 { + sign = true // odd n and negative x + } + } + var b float64 + if float64(n) <= x { + // Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) + if x >= Two302 { // x > 2**302 + + // (x >> n**2) + // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + // Let s=sin(x), c=cos(x), + // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + // + // n sin(xn)*sqt2 cos(xn)*sqt2 + // ---------------------------------- + // 0 s-c c+s + // 1 -s-c -c+s + // 2 -s+c -c-s + // 3 s+c c-s + + var temp float64 + switch s, c := Sincos(x); n & 3 { + case 0: + temp = c + s + case 1: + temp = -c + s + case 2: + temp = -c - s + case 3: + temp = c - s + } + b = (1 / SqrtPi) * temp / Sqrt(x) + } else { + b = J1(x) + for i, a := 1, J0(x); i < n; i++ { + a, b = b, b*(float64(i+i)/x)-a // avoid underflow + } + } + } else { + if x < TwoM29 { // x < 2**-29 + // x is tiny, return the first Taylor expansion of J(n,x) + // J(n,x) = 1/n!*(x/2)**n - ... + + if n > 33 { // underflow + b = 0 + } else { + temp := x * 0.5 + b = temp + a := 1.0 + for i := 2; i <= n; i++ { + a *= float64(i) // a = n! + b *= temp // b = (x/2)**n + } + b /= a + } + } else { + // use backward recurrence + // x x**2 x**2 + // J(n,x)/J(n-1,x) = ---- ------ ------ ..... + // 2n - 2(n+1) - 2(n+2) + // + // 1 1 1 + // (for large x) = ---- ------ ------ ..... + // 2n 2(n+1) 2(n+2) + // -- - ------ - ------ - + // x x x + // + // Let w = 2n/x and h=2/x, then the above quotient + // is equal to the continued fraction: + // 1 + // = ----------------------- + // 1 + // w - ----------------- + // 1 + // w+h - --------- + // w+2h - ... + // + // To determine how many terms needed, let + // Q(0) = w, Q(1) = w(w+h) - 1, + // Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + // When Q(k) > 1e4 good for single + // When Q(k) > 1e9 good for double + // When Q(k) > 1e17 good for quadruple + + // determine k + w := float64(n+n) / x + h := 2 / x + q0 := w + z := w + h + q1 := w*z - 1 + k := 1 + for q1 < 1e9 { + k++ + z += h + q0, q1 = q1, z*q1-q0 + } + m := n + n + t := 0.0 + for i := 2 * (n + k); i >= m; i -= 2 { + t = 1 / (float64(i)/x - t) + } + a := t + b = 1 + // estimate log((2/x)**n*n!) = n*log(2/x)+n*ln(n) + // Hence, if n*(log(2n/x)) > ... + // single 8.8722839355e+01 + // double 7.09782712893383973096e+02 + // long double 1.1356523406294143949491931077970765006170e+04 + // then recurrent value may overflow and the result is + // likely underflow to zero + + tmp := float64(n) + v := 2 / x + tmp = tmp * Log(Abs(v*tmp)) + if tmp < 7.09782712893383973096e+02 { + for i := n - 1; i > 0; i-- { + di := float64(i + i) + a, b = b, b*di/x-a + } + } else { + for i := n - 1; i > 0; i-- { + di := float64(i + i) + a, b = b, b*di/x-a + // scale b to avoid spurious overflow + if b > 1e100 { + a /= b + t /= b + b = 1 + } + } + } + b = t * J0(x) / b + } + } + if sign { + return -b + } + return b +} + +// Yn returns the order-n Bessel function of the second kind. +// +// Special cases are: +// Yn(n, +Inf) = 0 +// Yn(n ≥ 0, 0) = -Inf +// Yn(n < 0, 0) = +Inf if n is odd, -Inf if n is even +// Yn(n, x < 0) = NaN +// Yn(n, NaN) = NaN +func Yn(n int, x float64) float64 { + const Two302 = 1 << 302 // 2**302 0x52D0000000000000 + // special cases + switch { + case x < 0 || IsNaN(x): + return NaN() + case IsInf(x, 1): + return 0 + } + + if n == 0 { + return Y0(x) + } + if x == 0 { + if n < 0 && n&1 == 1 { + return Inf(1) + } + return Inf(-1) + } + sign := false + if n < 0 { + n = -n + if n&1 == 1 { + sign = true // sign true if n < 0 && |n| odd + } + } + if n == 1 { + if sign { + return -Y1(x) + } + return Y1(x) + } + var b float64 + if x >= Two302 { // x > 2**302 + // (x >> n**2) + // Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + // Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + // Let s=sin(x), c=cos(x), + // xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + // + // n sin(xn)*sqt2 cos(xn)*sqt2 + // ---------------------------------- + // 0 s-c c+s + // 1 -s-c -c+s + // 2 -s+c -c-s + // 3 s+c c-s + + var temp float64 + switch s, c := Sincos(x); n & 3 { + case 0: + temp = s - c + case 1: + temp = -s - c + case 2: + temp = -s + c + case 3: + temp = s + c + } + b = (1 / SqrtPi) * temp / Sqrt(x) + } else { + a := Y0(x) + b = Y1(x) + // quit if b is -inf + for i := 1; i < n && !IsInf(b, -1); i++ { + a, b = b, (float64(i+i)/x)*b-a + } + } + if sign { + return -b + } + return b +} diff --git a/contrib/go/_std_1.18/src/math/ldexp.go b/contrib/go/_std_1.18/src/math/ldexp.go new file mode 100644 index 0000000000..55c82f1e84 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/ldexp.go @@ -0,0 +1,50 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Ldexp is the inverse of Frexp. +// It returns frac × 2**exp. +// +// Special cases are: +// Ldexp(±0, exp) = ±0 +// Ldexp(±Inf, exp) = ±Inf +// Ldexp(NaN, exp) = NaN +func Ldexp(frac float64, exp int) float64 { + if haveArchLdexp { + return archLdexp(frac, exp) + } + return ldexp(frac, exp) +} + +func ldexp(frac float64, exp int) float64 { + // special cases + switch { + case frac == 0: + return frac // correctly return -0 + case IsInf(frac, 0) || IsNaN(frac): + return frac + } + frac, e := normalize(frac) + exp += e + x := Float64bits(frac) + exp += int(x>>shift)&mask - bias + if exp < -1075 { + return Copysign(0, frac) // underflow + } + if exp > 1023 { // overflow + if frac < 0 { + return Inf(-1) + } + return Inf(1) + } + var m float64 = 1 + if exp < -1022 { // denormal + exp += 53 + m = 1.0 / (1 << 53) // 2**-53 + } + x &^= mask << shift + x |= uint64(exp+bias) << shift + return m * Float64frombits(x) +} diff --git a/contrib/go/_std_1.18/src/math/lgamma.go b/contrib/go/_std_1.18/src/math/lgamma.go new file mode 100644 index 0000000000..7af5871744 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/lgamma.go @@ -0,0 +1,365 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point logarithm of the Gamma function. +*/ + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/e_lgamma_r.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_lgamma_r(x, signgamp) +// Reentrant version of the logarithm of the Gamma function +// with user provided pointer for the sign of Gamma(x). +// +// Method: +// 1. Argument Reduction for 0 < x <= 8 +// Since gamma(1+s)=s*gamma(s), for x in [0,8], we may +// reduce x to a number in [1.5,2.5] by +// lgamma(1+s) = log(s) + lgamma(s) +// for example, +// lgamma(7.3) = log(6.3) + lgamma(6.3) +// = log(6.3*5.3) + lgamma(5.3) +// = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) +// 2. Polynomial approximation of lgamma around its +// minimum (ymin=1.461632144968362245) to maintain monotonicity. +// On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use +// Let z = x-ymin; +// lgamma(x) = -1.214862905358496078218 + z**2*poly(z) +// poly(z) is a 14 degree polynomial. +// 2. Rational approximation in the primary interval [2,3] +// We use the following approximation: +// s = x-2.0; +// lgamma(x) = 0.5*s + s*P(s)/Q(s) +// with accuracy +// |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 +// Our algorithms are based on the following observation +// +// zeta(2)-1 2 zeta(3)-1 3 +// lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... +// 2 3 +// +// where Euler = 0.5772156649... is the Euler constant, which +// is very close to 0.5. +// +// 3. For x>=8, we have +// lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... +// (better formula: +// lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) +// Let z = 1/x, then we approximation +// f(z) = lgamma(x) - (x-0.5)(log(x)-1) +// by +// 3 5 11 +// w = w0 + w1*z + w2*z + w3*z + ... + w6*z +// where +// |w - f(z)| < 2**-58.74 +// +// 4. For negative x, since (G is gamma function) +// -x*G(-x)*G(x) = pi/sin(pi*x), +// we have +// G(x) = pi/(sin(pi*x)*(-x)*G(-x)) +// since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 +// Hence, for x<0, signgam = sign(sin(pi*x)) and +// lgamma(x) = log(|Gamma(x)|) +// = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); +// Note: one should avoid computing pi*(-x) directly in the +// computation of sin(pi*(-x)). +// +// 5. Special Cases +// lgamma(2+s) ~ s*(1-Euler) for tiny s +// lgamma(1)=lgamma(2)=0 +// lgamma(x) ~ -log(x) for tiny x +// lgamma(0) = lgamma(inf) = inf +// lgamma(-integer) = +-inf +// +// + +var _lgamA = [...]float64{ + 7.72156649015328655494e-02, // 0x3FB3C467E37DB0C8 + 3.22467033424113591611e-01, // 0x3FD4A34CC4A60FAD + 6.73523010531292681824e-02, // 0x3FB13E001A5562A7 + 2.05808084325167332806e-02, // 0x3F951322AC92547B + 7.38555086081402883957e-03, // 0x3F7E404FB68FEFE8 + 2.89051383673415629091e-03, // 0x3F67ADD8CCB7926B + 1.19270763183362067845e-03, // 0x3F538A94116F3F5D + 5.10069792153511336608e-04, // 0x3F40B6C689B99C00 + 2.20862790713908385557e-04, // 0x3F2CF2ECED10E54D + 1.08011567247583939954e-04, // 0x3F1C5088987DFB07 + 2.52144565451257326939e-05, // 0x3EFA7074428CFA52 + 4.48640949618915160150e-05, // 0x3F07858E90A45837 +} +var _lgamR = [...]float64{ + 1.0, // placeholder + 1.39200533467621045958e+00, // 0x3FF645A762C4AB74 + 7.21935547567138069525e-01, // 0x3FE71A1893D3DCDC + 1.71933865632803078993e-01, // 0x3FC601EDCCFBDF27 + 1.86459191715652901344e-02, // 0x3F9317EA742ED475 + 7.77942496381893596434e-04, // 0x3F497DDACA41A95B + 7.32668430744625636189e-06, // 0x3EDEBAF7A5B38140 +} +var _lgamS = [...]float64{ + -7.72156649015328655494e-02, // 0xBFB3C467E37DB0C8 + 2.14982415960608852501e-01, // 0x3FCB848B36E20878 + 3.25778796408930981787e-01, // 0x3FD4D98F4F139F59 + 1.46350472652464452805e-01, // 0x3FC2BB9CBEE5F2F7 + 2.66422703033638609560e-02, // 0x3F9B481C7E939961 + 1.84028451407337715652e-03, // 0x3F5E26B67368F239 + 3.19475326584100867617e-05, // 0x3F00BFECDD17E945 +} +var _lgamT = [...]float64{ + 4.83836122723810047042e-01, // 0x3FDEF72BC8EE38A2 + -1.47587722994593911752e-01, // 0xBFC2E4278DC6C509 + 6.46249402391333854778e-02, // 0x3FB08B4294D5419B + -3.27885410759859649565e-02, // 0xBFA0C9A8DF35B713 + 1.79706750811820387126e-02, // 0x3F9266E7970AF9EC + -1.03142241298341437450e-02, // 0xBF851F9FBA91EC6A + 6.10053870246291332635e-03, // 0x3F78FCE0E370E344 + -3.68452016781138256760e-03, // 0xBF6E2EFFB3E914D7 + 2.25964780900612472250e-03, // 0x3F6282D32E15C915 + -1.40346469989232843813e-03, // 0xBF56FE8EBF2D1AF1 + 8.81081882437654011382e-04, // 0x3F4CDF0CEF61A8E9 + -5.38595305356740546715e-04, // 0xBF41A6109C73E0EC + 3.15632070903625950361e-04, // 0x3F34AF6D6C0EBBF7 + -3.12754168375120860518e-04, // 0xBF347F24ECC38C38 + 3.35529192635519073543e-04, // 0x3F35FD3EE8C2D3F4 +} +var _lgamU = [...]float64{ + -7.72156649015328655494e-02, // 0xBFB3C467E37DB0C8 + 6.32827064025093366517e-01, // 0x3FE4401E8B005DFF + 1.45492250137234768737e+00, // 0x3FF7475CD119BD6F + 9.77717527963372745603e-01, // 0x3FEF497644EA8450 + 2.28963728064692451092e-01, // 0x3FCD4EAEF6010924 + 1.33810918536787660377e-02, // 0x3F8B678BBF2BAB09 +} +var _lgamV = [...]float64{ + 1.0, + 2.45597793713041134822e+00, // 0x4003A5D7C2BD619C + 2.12848976379893395361e+00, // 0x40010725A42B18F5 + 7.69285150456672783825e-01, // 0x3FE89DFBE45050AF + 1.04222645593369134254e-01, // 0x3FBAAE55D6537C88 + 3.21709242282423911810e-03, // 0x3F6A5ABB57D0CF61 +} +var _lgamW = [...]float64{ + 4.18938533204672725052e-01, // 0x3FDACFE390C97D69 + 8.33333333333329678849e-02, // 0x3FB555555555553B + -2.77777777728775536470e-03, // 0xBF66C16C16B02E5C + 7.93650558643019558500e-04, // 0x3F4A019F98CF38B6 + -5.95187557450339963135e-04, // 0xBF4380CB8C0FE741 + 8.36339918996282139126e-04, // 0x3F4B67BA4CDAD5D1 + -1.63092934096575273989e-03, // 0xBF5AB89D0B9E43E4 +} + +// Lgamma returns the natural logarithm and sign (-1 or +1) of Gamma(x). +// +// Special cases are: +// Lgamma(+Inf) = +Inf +// Lgamma(0) = +Inf +// Lgamma(-integer) = +Inf +// Lgamma(-Inf) = -Inf +// Lgamma(NaN) = NaN +func Lgamma(x float64) (lgamma float64, sign int) { + const ( + Ymin = 1.461632144968362245 + Two52 = 1 << 52 // 0x4330000000000000 ~4.5036e+15 + Two53 = 1 << 53 // 0x4340000000000000 ~9.0072e+15 + Two58 = 1 << 58 // 0x4390000000000000 ~2.8823e+17 + Tiny = 1.0 / (1 << 70) // 0x3b90000000000000 ~8.47033e-22 + Tc = 1.46163214496836224576e+00 // 0x3FF762D86356BE3F + Tf = -1.21486290535849611461e-01 // 0xBFBF19B9BCC38A42 + // Tt = -(tail of Tf) + Tt = -3.63867699703950536541e-18 // 0xBC50C7CAA48A971F + ) + // special cases + sign = 1 + switch { + case IsNaN(x): + lgamma = x + return + case IsInf(x, 0): + lgamma = x + return + case x == 0: + lgamma = Inf(1) + return + } + + neg := false + if x < 0 { + x = -x + neg = true + } + + if x < Tiny { // if |x| < 2**-70, return -log(|x|) + if neg { + sign = -1 + } + lgamma = -Log(x) + return + } + var nadj float64 + if neg { + if x >= Two52 { // |x| >= 2**52, must be -integer + lgamma = Inf(1) + return + } + t := sinPi(x) + if t == 0 { + lgamma = Inf(1) // -integer + return + } + nadj = Log(Pi / Abs(t*x)) + if t < 0 { + sign = -1 + } + } + + switch { + case x == 1 || x == 2: // purge off 1 and 2 + lgamma = 0 + return + case x < 2: // use lgamma(x) = lgamma(x+1) - log(x) + var y float64 + var i int + if x <= 0.9 { + lgamma = -Log(x) + switch { + case x >= (Ymin - 1 + 0.27): // 0.7316 <= x <= 0.9 + y = 1 - x + i = 0 + case x >= (Ymin - 1 - 0.27): // 0.2316 <= x < 0.7316 + y = x - (Tc - 1) + i = 1 + default: // 0 < x < 0.2316 + y = x + i = 2 + } + } else { + lgamma = 0 + switch { + case x >= (Ymin + 0.27): // 1.7316 <= x < 2 + y = 2 - x + i = 0 + case x >= (Ymin - 0.27): // 1.2316 <= x < 1.7316 + y = x - Tc + i = 1 + default: // 0.9 < x < 1.2316 + y = x - 1 + i = 2 + } + } + switch i { + case 0: + z := y * y + p1 := _lgamA[0] + z*(_lgamA[2]+z*(_lgamA[4]+z*(_lgamA[6]+z*(_lgamA[8]+z*_lgamA[10])))) + p2 := z * (_lgamA[1] + z*(+_lgamA[3]+z*(_lgamA[5]+z*(_lgamA[7]+z*(_lgamA[9]+z*_lgamA[11]))))) + p := y*p1 + p2 + lgamma += (p - 0.5*y) + case 1: + z := y * y + w := z * y + p1 := _lgamT[0] + w*(_lgamT[3]+w*(_lgamT[6]+w*(_lgamT[9]+w*_lgamT[12]))) // parallel comp + p2 := _lgamT[1] + w*(_lgamT[4]+w*(_lgamT[7]+w*(_lgamT[10]+w*_lgamT[13]))) + p3 := _lgamT[2] + w*(_lgamT[5]+w*(_lgamT[8]+w*(_lgamT[11]+w*_lgamT[14]))) + p := z*p1 - (Tt - w*(p2+y*p3)) + lgamma += (Tf + p) + case 2: + p1 := y * (_lgamU[0] + y*(_lgamU[1]+y*(_lgamU[2]+y*(_lgamU[3]+y*(_lgamU[4]+y*_lgamU[5]))))) + p2 := 1 + y*(_lgamV[1]+y*(_lgamV[2]+y*(_lgamV[3]+y*(_lgamV[4]+y*_lgamV[5])))) + lgamma += (-0.5*y + p1/p2) + } + case x < 8: // 2 <= x < 8 + i := int(x) + y := x - float64(i) + p := y * (_lgamS[0] + y*(_lgamS[1]+y*(_lgamS[2]+y*(_lgamS[3]+y*(_lgamS[4]+y*(_lgamS[5]+y*_lgamS[6])))))) + q := 1 + y*(_lgamR[1]+y*(_lgamR[2]+y*(_lgamR[3]+y*(_lgamR[4]+y*(_lgamR[5]+y*_lgamR[6]))))) + lgamma = 0.5*y + p/q + z := 1.0 // Lgamma(1+s) = Log(s) + Lgamma(s) + switch i { + case 7: + z *= (y + 6) + fallthrough + case 6: + z *= (y + 5) + fallthrough + case 5: + z *= (y + 4) + fallthrough + case 4: + z *= (y + 3) + fallthrough + case 3: + z *= (y + 2) + lgamma += Log(z) + } + case x < Two58: // 8 <= x < 2**58 + t := Log(x) + z := 1 / x + y := z * z + w := _lgamW[0] + z*(_lgamW[1]+y*(_lgamW[2]+y*(_lgamW[3]+y*(_lgamW[4]+y*(_lgamW[5]+y*_lgamW[6]))))) + lgamma = (x-0.5)*(t-1) + w + default: // 2**58 <= x <= Inf + lgamma = x * (Log(x) - 1) + } + if neg { + lgamma = nadj - lgamma + } + return +} + +// sinPi(x) is a helper function for negative x +func sinPi(x float64) float64 { + const ( + Two52 = 1 << 52 // 0x4330000000000000 ~4.5036e+15 + Two53 = 1 << 53 // 0x4340000000000000 ~9.0072e+15 + ) + if x < 0.25 { + return -Sin(Pi * x) + } + + // argument reduction + z := Floor(x) + var n int + if z != x { // inexact + x = Mod(x, 2) + n = int(x * 4) + } else { + if x >= Two53 { // x must be even + x = 0 + n = 0 + } else { + if x < Two52 { + z = x + Two52 // exact + } + n = int(1 & Float64bits(z)) + x = float64(n) + n <<= 2 + } + } + switch n { + case 0: + x = Sin(Pi * x) + case 1, 2: + x = Cos(Pi * (0.5 - x)) + case 3, 4: + x = Sin(Pi * (1 - x)) + case 5, 6: + x = -Cos(Pi * (x - 1.5)) + default: + x = Sin(Pi * (x - 2)) + } + return -x +} diff --git a/contrib/go/_std_1.18/src/math/log.go b/contrib/go/_std_1.18/src/math/log.go new file mode 100644 index 0000000000..1b3e306adf --- /dev/null +++ b/contrib/go/_std_1.18/src/math/log.go @@ -0,0 +1,128 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point logarithm. +*/ + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/e_log.c +// and came with this notice. The go code is a simpler +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_log(x) +// Return the logarithm of x +// +// Method : +// 1. Argument Reduction: find k and f such that +// x = 2**k * (1+f), +// where sqrt(2)/2 < 1+f < sqrt(2) . +// +// 2. Approximation of log(1+f). +// Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) +// = 2s + 2/3 s**3 + 2/5 s**5 + ....., +// = 2s + s*R +// We use a special Reme algorithm on [0,0.1716] to generate +// a polynomial of degree 14 to approximate R. The maximum error +// of this polynomial approximation is bounded by 2**-58.45. In +// other words, +// 2 4 6 8 10 12 14 +// R(z) ~ L1*s +L2*s +L3*s +L4*s +L5*s +L6*s +L7*s +// (the values of L1 to L7 are listed in the program) and +// | 2 14 | -58.45 +// | L1*s +...+L7*s - R(z) | <= 2 +// | | +// Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. +// In order to guarantee error in log below 1ulp, we compute log by +// log(1+f) = f - s*(f - R) (if f is not too large) +// log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) +// +// 3. Finally, log(x) = k*Ln2 + log(1+f). +// = k*Ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*Ln2_lo))) +// Here Ln2 is split into two floating point number: +// Ln2_hi + Ln2_lo, +// where n*Ln2_hi is always exact for |n| < 2000. +// +// Special cases: +// log(x) is NaN with signal if x < 0 (including -INF) ; +// log(+INF) is +INF; log(0) is -INF with signal; +// log(NaN) is that NaN with no signal. +// +// Accuracy: +// according to an error analysis, the error is always less than +// 1 ulp (unit in the last place). +// +// Constants: +// The hexadecimal values are the intended ones for the following +// constants. The decimal values may be used, provided that the +// compiler will convert from decimal to binary accurately enough +// to produce the hexadecimal values shown. + +// Log returns the natural logarithm of x. +// +// Special cases are: +// Log(+Inf) = +Inf +// Log(0) = -Inf +// Log(x < 0) = NaN +// Log(NaN) = NaN +func Log(x float64) float64 { + if haveArchLog { + return archLog(x) + } + return log(x) +} + +func log(x float64) float64 { + const ( + Ln2Hi = 6.93147180369123816490e-01 /* 3fe62e42 fee00000 */ + Ln2Lo = 1.90821492927058770002e-10 /* 3dea39ef 35793c76 */ + L1 = 6.666666666666735130e-01 /* 3FE55555 55555593 */ + L2 = 3.999999999940941908e-01 /* 3FD99999 9997FA04 */ + L3 = 2.857142874366239149e-01 /* 3FD24924 94229359 */ + L4 = 2.222219843214978396e-01 /* 3FCC71C5 1D8E78AF */ + L5 = 1.818357216161805012e-01 /* 3FC74664 96CB03DE */ + L6 = 1.531383769920937332e-01 /* 3FC39A09 D078C69F */ + L7 = 1.479819860511658591e-01 /* 3FC2F112 DF3E5244 */ + ) + + // special cases + switch { + case IsNaN(x) || IsInf(x, 1): + return x + case x < 0: + return NaN() + case x == 0: + return Inf(-1) + } + + // reduce + f1, ki := Frexp(x) + if f1 < Sqrt2/2 { + f1 *= 2 + ki-- + } + f := f1 - 1 + k := float64(ki) + + // compute + s := f / (2 + f) + s2 := s * s + s4 := s2 * s2 + t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7))) + t2 := s4 * (L2 + s4*(L4+s4*L6)) + R := t1 + t2 + hfsq := 0.5 * f * f + return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f) +} diff --git a/contrib/go/_std_1.18/src/math/log10.go b/contrib/go/_std_1.18/src/math/log10.go new file mode 100644 index 0000000000..e6916a53b6 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/log10.go @@ -0,0 +1,37 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Log10 returns the decimal logarithm of x. +// The special cases are the same as for Log. +func Log10(x float64) float64 { + if haveArchLog10 { + return archLog10(x) + } + return log10(x) +} + +func log10(x float64) float64 { + return Log(x) * (1 / Ln10) +} + +// Log2 returns the binary logarithm of x. +// The special cases are the same as for Log. +func Log2(x float64) float64 { + if haveArchLog2 { + return archLog2(x) + } + return log2(x) +} + +func log2(x float64) float64 { + frac, exp := Frexp(x) + // Make sure exact powers of two give an exact answer. + // Don't depend on Log(0.5)*(1/Ln2)+exp being exactly exp-1. + if frac == 0.5 { + return float64(exp - 1) + } + return Log(frac)*(1/Ln2) + float64(exp) +} diff --git a/contrib/go/_std_1.18/src/math/log1p.go b/contrib/go/_std_1.18/src/math/log1p.go new file mode 100644 index 0000000000..c117f7245d --- /dev/null +++ b/contrib/go/_std_1.18/src/math/log1p.go @@ -0,0 +1,202 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below are from FreeBSD's /usr/src/lib/msun/src/s_log1p.c +// and came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// +// double log1p(double x) +// +// Method : +// 1. Argument Reduction: find k and f such that +// 1+x = 2**k * (1+f), +// where sqrt(2)/2 < 1+f < sqrt(2) . +// +// Note. If k=0, then f=x is exact. However, if k!=0, then f +// may not be representable exactly. In that case, a correction +// term is need. Let u=1+x rounded. Let c = (1+x)-u, then +// log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), +// and add back the correction term c/u. +// (Note: when x > 2**53, one can simply return log(x)) +// +// 2. Approximation of log1p(f). +// Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) +// = 2s + 2/3 s**3 + 2/5 s**5 + ....., +// = 2s + s*R +// We use a special Reme algorithm on [0,0.1716] to generate +// a polynomial of degree 14 to approximate R The maximum error +// of this polynomial approximation is bounded by 2**-58.45. In +// other words, +// 2 4 6 8 10 12 14 +// R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s +// (the values of Lp1 to Lp7 are listed in the program) +// and +// | 2 14 | -58.45 +// | Lp1*s +...+Lp7*s - R(z) | <= 2 +// | | +// Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. +// In order to guarantee error in log below 1ulp, we compute log +// by +// log1p(f) = f - (hfsq - s*(hfsq+R)). +// +// 3. Finally, log1p(x) = k*ln2 + log1p(f). +// = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) +// Here ln2 is split into two floating point number: +// ln2_hi + ln2_lo, +// where n*ln2_hi is always exact for |n| < 2000. +// +// Special cases: +// log1p(x) is NaN with signal if x < -1 (including -INF) ; +// log1p(+INF) is +INF; log1p(-1) is -INF with signal; +// log1p(NaN) is that NaN with no signal. +// +// Accuracy: +// according to an error analysis, the error is always less than +// 1 ulp (unit in the last place). +// +// Constants: +// The hexadecimal values are the intended ones for the following +// constants. The decimal values may be used, provided that the +// compiler will convert from decimal to binary accurately enough +// to produce the hexadecimal values shown. +// +// Note: Assuming log() return accurate answer, the following +// algorithm can be used to compute log1p(x) to within a few ULP: +// +// u = 1+x; +// if(u==1.0) return x ; else +// return log(u)*(x/(u-1.0)); +// +// See HP-15C Advanced Functions Handbook, p.193. + +// Log1p returns the natural logarithm of 1 plus its argument x. +// It is more accurate than Log(1 + x) when x is near zero. +// +// Special cases are: +// Log1p(+Inf) = +Inf +// Log1p(±0) = ±0 +// Log1p(-1) = -Inf +// Log1p(x < -1) = NaN +// Log1p(NaN) = NaN +func Log1p(x float64) float64 { + if haveArchLog1p { + return archLog1p(x) + } + return log1p(x) +} + +func log1p(x float64) float64 { + const ( + Sqrt2M1 = 4.142135623730950488017e-01 // Sqrt(2)-1 = 0x3fda827999fcef34 + Sqrt2HalfM1 = -2.928932188134524755992e-01 // Sqrt(2)/2-1 = 0xbfd2bec333018866 + Small = 1.0 / (1 << 29) // 2**-29 = 0x3e20000000000000 + Tiny = 1.0 / (1 << 54) // 2**-54 + Two53 = 1 << 53 // 2**53 + Ln2Hi = 6.93147180369123816490e-01 // 3fe62e42fee00000 + Ln2Lo = 1.90821492927058770002e-10 // 3dea39ef35793c76 + Lp1 = 6.666666666666735130e-01 // 3FE5555555555593 + Lp2 = 3.999999999940941908e-01 // 3FD999999997FA04 + Lp3 = 2.857142874366239149e-01 // 3FD2492494229359 + Lp4 = 2.222219843214978396e-01 // 3FCC71C51D8E78AF + Lp5 = 1.818357216161805012e-01 // 3FC7466496CB03DE + Lp6 = 1.531383769920937332e-01 // 3FC39A09D078C69F + Lp7 = 1.479819860511658591e-01 // 3FC2F112DF3E5244 + ) + + // special cases + switch { + case x < -1 || IsNaN(x): // includes -Inf + return NaN() + case x == -1: + return Inf(-1) + case IsInf(x, 1): + return Inf(1) + } + + absx := Abs(x) + + var f float64 + var iu uint64 + k := 1 + if absx < Sqrt2M1 { // |x| < Sqrt(2)-1 + if absx < Small { // |x| < 2**-29 + if absx < Tiny { // |x| < 2**-54 + return x + } + return x - x*x*0.5 + } + if x > Sqrt2HalfM1 { // Sqrt(2)/2-1 < x + // (Sqrt(2)/2-1) < x < (Sqrt(2)-1) + k = 0 + f = x + iu = 1 + } + } + var c float64 + if k != 0 { + var u float64 + if absx < Two53 { // 1<<53 + u = 1.0 + x + iu = Float64bits(u) + k = int((iu >> 52) - 1023) + // correction term + if k > 0 { + c = 1.0 - (u - x) + } else { + c = x - (u - 1.0) + } + c /= u + } else { + u = x + iu = Float64bits(u) + k = int((iu >> 52) - 1023) + c = 0 + } + iu &= 0x000fffffffffffff + if iu < 0x0006a09e667f3bcd { // mantissa of Sqrt(2) + u = Float64frombits(iu | 0x3ff0000000000000) // normalize u + } else { + k++ + u = Float64frombits(iu | 0x3fe0000000000000) // normalize u/2 + iu = (0x0010000000000000 - iu) >> 2 + } + f = u - 1.0 // Sqrt(2)/2 < u < Sqrt(2) + } + hfsq := 0.5 * f * f + var s, R, z float64 + if iu == 0 { // |f| < 2**-20 + if f == 0 { + if k == 0 { + return 0 + } + c += float64(k) * Ln2Lo + return float64(k)*Ln2Hi + c + } + R = hfsq * (1.0 - 0.66666666666666666*f) // avoid division + if k == 0 { + return f - R + } + return float64(k)*Ln2Hi - ((R - (float64(k)*Ln2Lo + c)) - f) + } + s = f / (2.0 + f) + z = s * s + R = z * (Lp1 + z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))) + if k == 0 { + return f - (hfsq - s*(hfsq+R)) + } + return float64(k)*Ln2Hi - ((hfsq - (s*(hfsq+R) + (float64(k)*Ln2Lo + c))) - f) +} diff --git a/contrib/go/_std_1.18/src/math/log_amd64.s b/contrib/go/_std_1.18/src/math/log_amd64.s new file mode 100644 index 0000000000..d84091f23a --- /dev/null +++ b/contrib/go/_std_1.18/src/math/log_amd64.s @@ -0,0 +1,112 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +#define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2 +#define Ln2Hi 6.93147180369123816490e-01 // 0x3fe62e42fee00000 +#define Ln2Lo 1.90821492927058770002e-10 // 0x3dea39ef35793c76 +#define L1 6.666666666666735130e-01 // 0x3FE5555555555593 +#define L2 3.999999999940941908e-01 // 0x3FD999999997FA04 +#define L3 2.857142874366239149e-01 // 0x3FD2492494229359 +#define L4 2.222219843214978396e-01 // 0x3FCC71C51D8E78AF +#define L5 1.818357216161805012e-01 // 0x3FC7466496CB03DE +#define L6 1.531383769920937332e-01 // 0x3FC39A09D078C69F +#define L7 1.479819860511658591e-01 // 0x3FC2F112DF3E5244 +#define NaN 0x7FF8000000000001 +#define NegInf 0xFFF0000000000000 +#define PosInf 0x7FF0000000000000 + +// func Log(x float64) float64 +TEXT ·archLog(SB),NOSPLIT,$0 + // test bits for special cases + MOVQ x+0(FP), BX + MOVQ $~(1<<63), AX // sign bit mask + ANDQ BX, AX + JEQ isZero + MOVQ $0, AX + CMPQ AX, BX + JGT isNegative + MOVQ $PosInf, AX + CMPQ AX, BX + JLE isInfOrNaN + // f1, ki := math.Frexp(x); k := float64(ki) + MOVQ BX, X0 + MOVQ $0x000FFFFFFFFFFFFF, AX + MOVQ AX, X2 + ANDPD X0, X2 + MOVSD $0.5, X0 // 0x3FE0000000000000 + ORPD X0, X2 // X2= f1 + SHRQ $52, BX + ANDL $0x7FF, BX + SUBL $0x3FE, BX + XORPS X1, X1 // break dependency for CVTSL2SD + CVTSL2SD BX, X1 // x1= k, x2= f1 + // if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 } + MOVSD $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1 + CMPSD X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1 + MOVSD $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1 + ANDPD X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1 + SUBSD X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1 + MOVSD $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1 + ADDSD X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2 + MULSD X3, X2 // x0= 1, x1= k, x2= f1 + // f := f1 - 1 + SUBSD X0, X2 // x1= k, x2= f + // s := f / (2 + f) + MOVSD $2.0, X0 + ADDSD X2, X0 + MOVAPD X2, X3 + DIVSD X0, X3 // x1=k, x2= f, x3= s + // s2 := s * s + MOVAPD X3, X4 // x1= k, x2= f, x3= s + MULSD X4, X4 // x1= k, x2= f, x3= s, x4= s2 + // s4 := s2 * s2 + MOVAPD X4, X5 // x1= k, x2= f, x3= s, x4= s2 + MULSD X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4 + // t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7))) + MOVSD $L7, X6 + MULSD X5, X6 + ADDSD $L5, X6 + MULSD X5, X6 + ADDSD $L3, X6 + MULSD X5, X6 + ADDSD $L1, X6 + MULSD X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4 + // t2 := s4 * (L2 + s4*(L4+s4*L6)) + MOVSD $L6, X6 + MULSD X5, X6 + ADDSD $L4, X6 + MULSD X5, X6 + ADDSD $L2, X6 + MULSD X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2 + // R := t1 + t2 + ADDSD X5, X4 // x1= k, x2= f, x3= s, x4= R + // hfsq := 0.5 * f * f + MOVSD $0.5, X0 + MULSD X2, X0 + MULSD X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R + // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f) + ADDSD X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R + MULSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R) + MOVSD $Ln2Lo, X4 + MULSD X1, X4 // x4= k*Ln2Lo + ADDSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo + SUBSD X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f + SUBSD X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k + MULSD $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi + SUBSD X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f) + MOVSD X1, ret+8(FP) + RET +isInfOrNaN: + MOVQ BX, ret+8(FP) // +Inf or NaN, return x + RET +isNegative: + MOVQ $NaN, AX + MOVQ AX, ret+8(FP) // return NaN + RET +isZero: + MOVQ $NegInf, AX + MOVQ AX, ret+8(FP) // return -Inf + RET diff --git a/contrib/go/_std_1.18/src/math/log_asm.go b/contrib/go/_std_1.18/src/math/log_asm.go new file mode 100644 index 0000000000..848cce13b2 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/log_asm.go @@ -0,0 +1,11 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build amd64 || s390x + +package math + +const haveArchLog = true + +func archLog(x float64) float64 diff --git a/contrib/go/_std_1.18/src/math/logb.go b/contrib/go/_std_1.18/src/math/logb.go new file mode 100644 index 0000000000..f2769d4fd7 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/logb.go @@ -0,0 +1,50 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Logb returns the binary exponent of x. +// +// Special cases are: +// Logb(±Inf) = +Inf +// Logb(0) = -Inf +// Logb(NaN) = NaN +func Logb(x float64) float64 { + // special cases + switch { + case x == 0: + return Inf(-1) + case IsInf(x, 0): + return Inf(1) + case IsNaN(x): + return x + } + return float64(ilogb(x)) +} + +// Ilogb returns the binary exponent of x as an integer. +// +// Special cases are: +// Ilogb(±Inf) = MaxInt32 +// Ilogb(0) = MinInt32 +// Ilogb(NaN) = MaxInt32 +func Ilogb(x float64) int { + // special cases + switch { + case x == 0: + return MinInt32 + case IsNaN(x): + return MaxInt32 + case IsInf(x, 0): + return MaxInt32 + } + return ilogb(x) +} + +// logb returns the binary exponent of x. It assumes x is finite and +// non-zero. +func ilogb(x float64) int { + x, exp := normalize(x) + return int((Float64bits(x)>>shift)&mask) - bias + exp +} diff --git a/contrib/go/_std_1.18/src/math/mod.go b/contrib/go/_std_1.18/src/math/mod.go new file mode 100644 index 0000000000..6bc5f28832 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/mod.go @@ -0,0 +1,51 @@ +// Copyright 2009-2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point mod function. +*/ + +// Mod returns the floating-point remainder of x/y. +// The magnitude of the result is less than y and its +// sign agrees with that of x. +// +// Special cases are: +// Mod(±Inf, y) = NaN +// Mod(NaN, y) = NaN +// Mod(x, 0) = NaN +// Mod(x, ±Inf) = x +// Mod(x, NaN) = NaN +func Mod(x, y float64) float64 { + if haveArchMod { + return archMod(x, y) + } + return mod(x, y) +} + +func mod(x, y float64) float64 { + if y == 0 || IsInf(x, 0) || IsNaN(x) || IsNaN(y) { + return NaN() + } + y = Abs(y) + + yfr, yexp := Frexp(y) + r := x + if x < 0 { + r = -x + } + + for r >= y { + rfr, rexp := Frexp(r) + if rfr < yfr { + rexp = rexp - 1 + } + r = r - Ldexp(y, rexp-yexp) + } + if x < 0 { + r = -r + } + return r +} diff --git a/contrib/go/_std_1.18/src/math/modf.go b/contrib/go/_std_1.18/src/math/modf.go new file mode 100644 index 0000000000..bf08dc6556 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/modf.go @@ -0,0 +1,42 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Modf returns integer and fractional floating-point numbers +// that sum to f. Both values have the same sign as f. +// +// Special cases are: +// Modf(±Inf) = ±Inf, NaN +// Modf(NaN) = NaN, NaN +func Modf(f float64) (int float64, frac float64) { + if haveArchModf { + return archModf(f) + } + return modf(f) +} + +func modf(f float64) (int float64, frac float64) { + if f < 1 { + switch { + case f < 0: + int, frac = Modf(-f) + return -int, -frac + case f == 0: + return f, f // Return -0, -0 when f == -0 + } + return 0, f + } + + x := Float64bits(f) + e := uint(x>>shift)&mask - bias + + // Keep the top 12+e bits, the integer part; clear the rest. + if e < 64-12 { + x &^= 1<<(64-12-e) - 1 + } + int = Float64frombits(x) + frac = f - int + return +} diff --git a/contrib/go/_std_1.18/src/math/modf_noasm.go b/contrib/go/_std_1.18/src/math/modf_noasm.go new file mode 100644 index 0000000000..55c6a7f6e2 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/modf_noasm.go @@ -0,0 +1,13 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !arm64 && !ppc64 && !ppc64le + +package math + +const haveArchModf = false + +func archModf(f float64) (int float64, frac float64) { + panic("not implemented") +} diff --git a/contrib/go/_std_1.18/src/math/nextafter.go b/contrib/go/_std_1.18/src/math/nextafter.go new file mode 100644 index 0000000000..9088e4d248 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/nextafter.go @@ -0,0 +1,49 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Nextafter32 returns the next representable float32 value after x towards y. +// +// Special cases are: +// Nextafter32(x, x) = x +// Nextafter32(NaN, y) = NaN +// Nextafter32(x, NaN) = NaN +func Nextafter32(x, y float32) (r float32) { + switch { + case IsNaN(float64(x)) || IsNaN(float64(y)): // special case + r = float32(NaN()) + case x == y: + r = x + case x == 0: + r = float32(Copysign(float64(Float32frombits(1)), float64(y))) + case (y > x) == (x > 0): + r = Float32frombits(Float32bits(x) + 1) + default: + r = Float32frombits(Float32bits(x) - 1) + } + return +} + +// Nextafter returns the next representable float64 value after x towards y. +// +// Special cases are: +// Nextafter(x, x) = x +// Nextafter(NaN, y) = NaN +// Nextafter(x, NaN) = NaN +func Nextafter(x, y float64) (r float64) { + switch { + case IsNaN(x) || IsNaN(y): // special case + r = NaN() + case x == y: + r = x + case x == 0: + r = Copysign(Float64frombits(1), y) + case (y > x) == (x > 0): + r = Float64frombits(Float64bits(x) + 1) + default: + r = Float64frombits(Float64bits(x) - 1) + } + return +} diff --git a/contrib/go/_std_1.18/src/math/pow.go b/contrib/go/_std_1.18/src/math/pow.go new file mode 100644 index 0000000000..e45a044ae1 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/pow.go @@ -0,0 +1,156 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +func isOddInt(x float64) bool { + xi, xf := Modf(x) + return xf == 0 && int64(xi)&1 == 1 +} + +// Special cases taken from FreeBSD's /usr/src/lib/msun/src/e_pow.c +// updated by IEEE Std. 754-2008 "Section 9.2.1 Special values". + +// Pow returns x**y, the base-x exponential of y. +// +// Special cases are (in order): +// Pow(x, ±0) = 1 for any x +// Pow(1, y) = 1 for any y +// Pow(x, 1) = x for any x +// Pow(NaN, y) = NaN +// Pow(x, NaN) = NaN +// Pow(±0, y) = ±Inf for y an odd integer < 0 +// Pow(±0, -Inf) = +Inf +// Pow(±0, +Inf) = +0 +// Pow(±0, y) = +Inf for finite y < 0 and not an odd integer +// Pow(±0, y) = ±0 for y an odd integer > 0 +// Pow(±0, y) = +0 for finite y > 0 and not an odd integer +// Pow(-1, ±Inf) = 1 +// Pow(x, +Inf) = +Inf for |x| > 1 +// Pow(x, -Inf) = +0 for |x| > 1 +// Pow(x, +Inf) = +0 for |x| < 1 +// Pow(x, -Inf) = +Inf for |x| < 1 +// Pow(+Inf, y) = +Inf for y > 0 +// Pow(+Inf, y) = +0 for y < 0 +// Pow(-Inf, y) = Pow(-0, -y) +// Pow(x, y) = NaN for finite x < 0 and finite non-integer y +func Pow(x, y float64) float64 { + if haveArchPow { + return archPow(x, y) + } + return pow(x, y) +} + +func pow(x, y float64) float64 { + switch { + case y == 0 || x == 1: + return 1 + case y == 1: + return x + case IsNaN(x) || IsNaN(y): + return NaN() + case x == 0: + switch { + case y < 0: + if isOddInt(y) { + return Copysign(Inf(1), x) + } + return Inf(1) + case y > 0: + if isOddInt(y) { + return x + } + return 0 + } + case IsInf(y, 0): + switch { + case x == -1: + return 1 + case (Abs(x) < 1) == IsInf(y, 1): + return 0 + default: + return Inf(1) + } + case IsInf(x, 0): + if IsInf(x, -1) { + return Pow(1/x, -y) // Pow(-0, -y) + } + switch { + case y < 0: + return 0 + case y > 0: + return Inf(1) + } + case y == 0.5: + return Sqrt(x) + case y == -0.5: + return 1 / Sqrt(x) + } + + yi, yf := Modf(Abs(y)) + if yf != 0 && x < 0 { + return NaN() + } + if yi >= 1<<63 { + // yi is a large even int that will lead to overflow (or underflow to 0) + // for all x except -1 (x == 1 was handled earlier) + switch { + case x == -1: + return 1 + case (Abs(x) < 1) == (y > 0): + return 0 + default: + return Inf(1) + } + } + + // ans = a1 * 2**ae (= 1 for now). + a1 := 1.0 + ae := 0 + + // ans *= x**yf + if yf != 0 { + if yf > 0.5 { + yf-- + yi++ + } + a1 = Exp(yf * Log(x)) + } + + // ans *= x**yi + // by multiplying in successive squarings + // of x according to bits of yi. + // accumulate powers of two into exp. + x1, xe := Frexp(x) + for i := int64(yi); i != 0; i >>= 1 { + if xe < -1<<12 || 1<<12 < xe { + // catch xe before it overflows the left shift below + // Since i !=0 it has at least one bit still set, so ae will accumulate xe + // on at least one more iteration, ae += xe is a lower bound on ae + // the lower bound on ae exceeds the size of a float64 exp + // so the final call to Ldexp will produce under/overflow (0/Inf) + ae += xe + break + } + if i&1 == 1 { + a1 *= x1 + ae += xe + } + x1 *= x1 + xe <<= 1 + if x1 < .5 { + x1 += x1 + xe-- + } + } + + // ans = a1*2**ae + // if y < 0 { ans = 1 / ans } + // but in the opposite order + if y < 0 { + a1 = 1 / a1 + ae = -ae + } + return Ldexp(a1, ae) +} diff --git a/contrib/go/_std_1.18/src/math/pow10.go b/contrib/go/_std_1.18/src/math/pow10.go new file mode 100644 index 0000000000..1234e20885 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/pow10.go @@ -0,0 +1,46 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// pow10tab stores the pre-computed values 10**i for i < 32. +var pow10tab = [...]float64{ + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, + 1e30, 1e31, +} + +// pow10postab32 stores the pre-computed value for 10**(i*32) at index i. +var pow10postab32 = [...]float64{ + 1e00, 1e32, 1e64, 1e96, 1e128, 1e160, 1e192, 1e224, 1e256, 1e288, +} + +// pow10negtab32 stores the pre-computed value for 10**(-i*32) at index i. +var pow10negtab32 = [...]float64{ + 1e-00, 1e-32, 1e-64, 1e-96, 1e-128, 1e-160, 1e-192, 1e-224, 1e-256, 1e-288, 1e-320, +} + +// Pow10 returns 10**n, the base-10 exponential of n. +// +// Special cases are: +// Pow10(n) = 0 for n < -323 +// Pow10(n) = +Inf for n > 308 +func Pow10(n int) float64 { + if 0 <= n && n <= 308 { + return pow10postab32[uint(n)/32] * pow10tab[uint(n)%32] + } + + if -323 <= n && n <= 0 { + return pow10negtab32[uint(-n)/32] / pow10tab[uint(-n)%32] + } + + // n < -323 || 308 < n + if n > 0 { + return Inf(1) + } + + // n < -323 + return 0 +} diff --git a/contrib/go/_std_1.18/src/math/rand/exp.go b/contrib/go/_std_1.18/src/math/rand/exp.go new file mode 100644 index 0000000000..5a8d946c0c --- /dev/null +++ b/contrib/go/_std_1.18/src/math/rand/exp.go @@ -0,0 +1,222 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package rand + +import ( + "math" +) + +/* + * Exponential distribution + * + * See "The Ziggurat Method for Generating Random Variables" + * (Marsaglia & Tsang, 2000) + * https://www.jstatsoft.org/v05/i08/paper [pdf] + */ + +const ( + re = 7.69711747013104972 +) + +// ExpFloat64 returns an exponentially distributed float64 in the range +// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter +// (lambda) is 1 and whose mean is 1/lambda (1). +// To produce a distribution with a different rate parameter, +// callers can adjust the output using: +// +// sample = ExpFloat64() / desiredRateParameter +// +func (r *Rand) ExpFloat64() float64 { + for { + j := r.Uint32() + i := j & 0xFF + x := float64(j) * float64(we[i]) + if j < ke[i] { + return x + } + if i == 0 { + return re - math.Log(r.Float64()) + } + if fe[i]+float32(r.Float64())*(fe[i-1]-fe[i]) < float32(math.Exp(-x)) { + return x + } + } +} + +var ke = [256]uint32{ + 0xe290a139, 0x0, 0x9beadebc, 0xc377ac71, 0xd4ddb990, + 0xde893fb8, 0xe4a8e87c, 0xe8dff16a, 0xebf2deab, 0xee49a6e8, + 0xf0204efd, 0xf19bdb8e, 0xf2d458bb, 0xf3da104b, 0xf4b86d78, + 0xf577ad8a, 0xf61de83d, 0xf6afb784, 0xf730a573, 0xf7a37651, + 0xf80a5bb6, 0xf867189d, 0xf8bb1b4f, 0xf9079062, 0xf94d70ca, + 0xf98d8c7d, 0xf9c8928a, 0xf9ff175b, 0xfa319996, 0xfa6085f8, + 0xfa8c3a62, 0xfab5084e, 0xfadb36c8, 0xfaff0410, 0xfb20a6ea, + 0xfb404fb4, 0xfb5e2951, 0xfb7a59e9, 0xfb95038c, 0xfbae44ba, + 0xfbc638d8, 0xfbdcf892, 0xfbf29a30, 0xfc0731df, 0xfc1ad1ed, + 0xfc2d8b02, 0xfc3f6c4d, 0xfc5083ac, 0xfc60ddd1, 0xfc708662, + 0xfc7f8810, 0xfc8decb4, 0xfc9bbd62, 0xfca9027c, 0xfcb5c3c3, + 0xfcc20864, 0xfccdd70a, 0xfcd935e3, 0xfce42ab0, 0xfceebace, + 0xfcf8eb3b, 0xfd02c0a0, 0xfd0c3f59, 0xfd156b7b, 0xfd1e48d6, + 0xfd26daff, 0xfd2f2552, 0xfd372af7, 0xfd3eeee5, 0xfd4673e7, + 0xfd4dbc9e, 0xfd54cb85, 0xfd5ba2f2, 0xfd62451b, 0xfd68b415, + 0xfd6ef1da, 0xfd750047, 0xfd7ae120, 0xfd809612, 0xfd8620b4, + 0xfd8b8285, 0xfd90bcf5, 0xfd95d15e, 0xfd9ac10b, 0xfd9f8d36, + 0xfda43708, 0xfda8bf9e, 0xfdad2806, 0xfdb17141, 0xfdb59c46, + 0xfdb9a9fd, 0xfdbd9b46, 0xfdc170f6, 0xfdc52bd8, 0xfdc8ccac, + 0xfdcc542d, 0xfdcfc30b, 0xfdd319ef, 0xfdd6597a, 0xfdd98245, + 0xfddc94e5, 0xfddf91e6, 0xfde279ce, 0xfde54d1f, 0xfde80c52, + 0xfdeab7de, 0xfded5034, 0xfdefd5be, 0xfdf248e3, 0xfdf4aa06, + 0xfdf6f984, 0xfdf937b6, 0xfdfb64f4, 0xfdfd818d, 0xfdff8dd0, + 0xfe018a08, 0xfe03767a, 0xfe05536c, 0xfe07211c, 0xfe08dfc9, + 0xfe0a8fab, 0xfe0c30fb, 0xfe0dc3ec, 0xfe0f48b1, 0xfe10bf76, + 0xfe122869, 0xfe1383b4, 0xfe14d17c, 0xfe1611e7, 0xfe174516, + 0xfe186b2a, 0xfe19843e, 0xfe1a9070, 0xfe1b8fd6, 0xfe1c8289, + 0xfe1d689b, 0xfe1e4220, 0xfe1f0f26, 0xfe1fcfbc, 0xfe2083ed, + 0xfe212bc3, 0xfe21c745, 0xfe225678, 0xfe22d95f, 0xfe234ffb, + 0xfe23ba4a, 0xfe241849, 0xfe2469f2, 0xfe24af3c, 0xfe24e81e, + 0xfe25148b, 0xfe253474, 0xfe2547c7, 0xfe254e70, 0xfe25485a, + 0xfe25356a, 0xfe251586, 0xfe24e88f, 0xfe24ae64, 0xfe2466e1, + 0xfe2411df, 0xfe23af34, 0xfe233eb4, 0xfe22c02c, 0xfe22336b, + 0xfe219838, 0xfe20ee58, 0xfe20358c, 0xfe1f6d92, 0xfe1e9621, + 0xfe1daef0, 0xfe1cb7ac, 0xfe1bb002, 0xfe1a9798, 0xfe196e0d, + 0xfe1832fd, 0xfe16e5fe, 0xfe15869d, 0xfe141464, 0xfe128ed3, + 0xfe10f565, 0xfe0f478c, 0xfe0d84b1, 0xfe0bac36, 0xfe09bd73, + 0xfe07b7b5, 0xfe059a40, 0xfe03644c, 0xfe011504, 0xfdfeab88, + 0xfdfc26e9, 0xfdf98629, 0xfdf6c83b, 0xfdf3ec01, 0xfdf0f04a, + 0xfdedd3d1, 0xfdea953d, 0xfde7331e, 0xfde3abe9, 0xfddffdfb, + 0xfddc2791, 0xfdd826cd, 0xfdd3f9a8, 0xfdcf9dfc, 0xfdcb1176, + 0xfdc65198, 0xfdc15bb3, 0xfdbc2ce2, 0xfdb6c206, 0xfdb117be, + 0xfdab2a63, 0xfda4f5fd, 0xfd9e7640, 0xfd97a67a, 0xfd908192, + 0xfd8901f2, 0xfd812182, 0xfd78d98e, 0xfd7022bb, 0xfd66f4ed, + 0xfd5d4732, 0xfd530f9c, 0xfd48432b, 0xfd3cd59a, 0xfd30b936, + 0xfd23dea4, 0xfd16349e, 0xfd07a7a3, 0xfcf8219b, 0xfce7895b, + 0xfcd5c220, 0xfcc2aadb, 0xfcae1d5e, 0xfc97ed4e, 0xfc7fe6d4, + 0xfc65ccf3, 0xfc495762, 0xfc2a2fc8, 0xfc07ee19, 0xfbe213c1, + 0xfbb8051a, 0xfb890078, 0xfb5411a5, 0xfb180005, 0xfad33482, + 0xfa839276, 0xfa263b32, 0xf9b72d1c, 0xf930a1a2, 0xf889f023, + 0xf7b577d2, 0xf69c650c, 0xf51530f0, 0xf2cb0e3c, 0xeeefb15d, + 0xe6da6ecf, +} +var we = [256]float32{ + 2.0249555e-09, 1.486674e-11, 2.4409617e-11, 3.1968806e-11, + 3.844677e-11, 4.4228204e-11, 4.9516443e-11, 5.443359e-11, + 5.905944e-11, 6.344942e-11, 6.7643814e-11, 7.1672945e-11, + 7.556032e-11, 7.932458e-11, 8.298079e-11, 8.654132e-11, + 9.0016515e-11, 9.3415074e-11, 9.674443e-11, 1.0001099e-10, + 1.03220314e-10, 1.06377254e-10, 1.09486115e-10, 1.1255068e-10, + 1.1557435e-10, 1.1856015e-10, 1.2151083e-10, 1.2442886e-10, + 1.2731648e-10, 1.3017575e-10, 1.3300853e-10, 1.3581657e-10, + 1.3860142e-10, 1.4136457e-10, 1.4410738e-10, 1.4683108e-10, + 1.4953687e-10, 1.5222583e-10, 1.54899e-10, 1.5755733e-10, + 1.6020171e-10, 1.6283301e-10, 1.6545203e-10, 1.6805951e-10, + 1.7065617e-10, 1.732427e-10, 1.7581973e-10, 1.7838787e-10, + 1.8094774e-10, 1.8349985e-10, 1.8604476e-10, 1.8858298e-10, + 1.9111498e-10, 1.9364126e-10, 1.9616223e-10, 1.9867835e-10, + 2.0119004e-10, 2.0369768e-10, 2.0620168e-10, 2.087024e-10, + 2.1120022e-10, 2.136955e-10, 2.1618855e-10, 2.1867974e-10, + 2.2116936e-10, 2.2365775e-10, 2.261452e-10, 2.2863202e-10, + 2.311185e-10, 2.3360494e-10, 2.360916e-10, 2.3857874e-10, + 2.4106667e-10, 2.4355562e-10, 2.4604588e-10, 2.485377e-10, + 2.5103128e-10, 2.5352695e-10, 2.560249e-10, 2.585254e-10, + 2.6102867e-10, 2.6353494e-10, 2.6604446e-10, 2.6855745e-10, + 2.7107416e-10, 2.7359479e-10, 2.761196e-10, 2.7864877e-10, + 2.8118255e-10, 2.8372119e-10, 2.8626485e-10, 2.888138e-10, + 2.9136826e-10, 2.939284e-10, 2.9649452e-10, 2.9906677e-10, + 3.016454e-10, 3.0423064e-10, 3.0682268e-10, 3.0942177e-10, + 3.1202813e-10, 3.1464195e-10, 3.1726352e-10, 3.19893e-10, + 3.2253064e-10, 3.251767e-10, 3.2783135e-10, 3.3049485e-10, + 3.3316744e-10, 3.3584938e-10, 3.3854083e-10, 3.4124212e-10, + 3.4395342e-10, 3.46675e-10, 3.4940711e-10, 3.5215003e-10, + 3.5490397e-10, 3.5766917e-10, 3.6044595e-10, 3.6323455e-10, + 3.660352e-10, 3.6884823e-10, 3.7167386e-10, 3.745124e-10, + 3.773641e-10, 3.802293e-10, 3.8310827e-10, 3.860013e-10, + 3.8890866e-10, 3.918307e-10, 3.9476775e-10, 3.9772008e-10, + 4.0068804e-10, 4.0367196e-10, 4.0667217e-10, 4.09689e-10, + 4.1272286e-10, 4.1577405e-10, 4.1884296e-10, 4.2192994e-10, + 4.250354e-10, 4.281597e-10, 4.313033e-10, 4.3446652e-10, + 4.3764986e-10, 4.408537e-10, 4.4407847e-10, 4.4732465e-10, + 4.5059267e-10, 4.5388301e-10, 4.571962e-10, 4.6053267e-10, + 4.6389292e-10, 4.6727755e-10, 4.70687e-10, 4.741219e-10, + 4.7758275e-10, 4.810702e-10, 4.845848e-10, 4.8812715e-10, + 4.9169796e-10, 4.9529775e-10, 4.989273e-10, 5.0258725e-10, + 5.0627835e-10, 5.100013e-10, 5.1375687e-10, 5.1754584e-10, + 5.21369e-10, 5.2522725e-10, 5.2912136e-10, 5.330522e-10, + 5.370208e-10, 5.4102806e-10, 5.45075e-10, 5.491625e-10, + 5.532918e-10, 5.5746385e-10, 5.616799e-10, 5.6594107e-10, + 5.7024857e-10, 5.746037e-10, 5.7900773e-10, 5.834621e-10, + 5.8796823e-10, 5.925276e-10, 5.971417e-10, 6.018122e-10, + 6.065408e-10, 6.113292e-10, 6.1617933e-10, 6.2109295e-10, + 6.260722e-10, 6.3111916e-10, 6.3623595e-10, 6.4142497e-10, + 6.4668854e-10, 6.5202926e-10, 6.5744976e-10, 6.6295286e-10, + 6.6854156e-10, 6.742188e-10, 6.79988e-10, 6.858526e-10, + 6.9181616e-10, 6.978826e-10, 7.04056e-10, 7.103407e-10, + 7.167412e-10, 7.2326256e-10, 7.2990985e-10, 7.366886e-10, + 7.4360473e-10, 7.5066453e-10, 7.5787476e-10, 7.6524265e-10, + 7.7277595e-10, 7.80483e-10, 7.883728e-10, 7.9645507e-10, + 8.047402e-10, 8.1323964e-10, 8.219657e-10, 8.309319e-10, + 8.401528e-10, 8.496445e-10, 8.594247e-10, 8.6951274e-10, + 8.799301e-10, 8.9070046e-10, 9.018503e-10, 9.134092e-10, + 9.254101e-10, 9.378904e-10, 9.508923e-10, 9.644638e-10, + 9.786603e-10, 9.935448e-10, 1.0091913e-09, 1.025686e-09, + 1.0431306e-09, 1.0616465e-09, 1.08138e-09, 1.1025096e-09, + 1.1252564e-09, 1.1498986e-09, 1.1767932e-09, 1.206409e-09, + 1.2393786e-09, 1.276585e-09, 1.3193139e-09, 1.3695435e-09, + 1.4305498e-09, 1.508365e-09, 1.6160854e-09, 1.7921248e-09, +} +var fe = [256]float32{ + 1, 0.9381437, 0.90046996, 0.87170434, 0.8477855, 0.8269933, + 0.8084217, 0.7915276, 0.77595687, 0.7614634, 0.7478686, + 0.7350381, 0.72286767, 0.71127474, 0.70019263, 0.6895665, + 0.67935055, 0.6695063, 0.66000086, 0.65080583, 0.6418967, + 0.63325197, 0.6248527, 0.6166822, 0.60872537, 0.60096896, + 0.5934009, 0.58601034, 0.5787874, 0.57172304, 0.5648092, + 0.5580383, 0.5514034, 0.5448982, 0.5385169, 0.53225386, + 0.5261042, 0.52006316, 0.5141264, 0.50828975, 0.5025495, + 0.496902, 0.49134386, 0.485872, 0.48048335, 0.4751752, + 0.46994483, 0.46478975, 0.45970762, 0.45469615, 0.44975325, + 0.44487688, 0.44006512, 0.43531612, 0.43062815, 0.42599955, + 0.42142874, 0.4169142, 0.41245446, 0.40804818, 0.403694, + 0.3993907, 0.39513698, 0.39093173, 0.38677382, 0.38266218, + 0.37859577, 0.37457356, 0.37059465, 0.3666581, 0.362763, + 0.35890847, 0.35509375, 0.351318, 0.3475805, 0.34388044, + 0.34021714, 0.3365899, 0.33299807, 0.32944095, 0.32591796, + 0.3224285, 0.3189719, 0.31554767, 0.31215525, 0.30879408, + 0.3054636, 0.3021634, 0.29889292, 0.2956517, 0.29243928, + 0.28925523, 0.28609908, 0.28297043, 0.27986884, 0.27679393, + 0.2737453, 0.2707226, 0.2677254, 0.26475343, 0.26180625, + 0.25888354, 0.25598502, 0.2531103, 0.25025907, 0.24743107, + 0.24462597, 0.24184346, 0.23908329, 0.23634516, 0.23362878, + 0.23093392, 0.2282603, 0.22560766, 0.22297576, 0.22036438, + 0.21777324, 0.21520215, 0.21265087, 0.21011916, 0.20760682, + 0.20511365, 0.20263945, 0.20018397, 0.19774707, 0.19532852, + 0.19292815, 0.19054577, 0.1881812, 0.18583426, 0.18350479, + 0.1811926, 0.17889754, 0.17661946, 0.17435817, 0.17211354, + 0.1698854, 0.16767362, 0.16547804, 0.16329853, 0.16113494, + 0.15898713, 0.15685499, 0.15473837, 0.15263714, 0.15055119, + 0.14848037, 0.14642459, 0.14438373, 0.14235765, 0.14034624, + 0.13834943, 0.13636707, 0.13439907, 0.13244532, 0.13050574, + 0.1285802, 0.12666863, 0.12477092, 0.12288698, 0.12101672, + 0.119160056, 0.1173169, 0.115487166, 0.11367077, 0.11186763, + 0.11007768, 0.10830083, 0.10653701, 0.10478614, 0.10304816, + 0.101323, 0.09961058, 0.09791085, 0.09622374, 0.09454919, + 0.09288713, 0.091237515, 0.08960028, 0.087975375, 0.08636274, + 0.08476233, 0.083174095, 0.081597984, 0.08003395, 0.07848195, + 0.076941945, 0.07541389, 0.07389775, 0.072393484, 0.07090106, + 0.069420435, 0.06795159, 0.066494495, 0.06504912, 0.063615434, + 0.062193416, 0.060783047, 0.059384305, 0.057997175, + 0.05662164, 0.05525769, 0.053905312, 0.052564494, 0.051235236, + 0.049917534, 0.048611384, 0.047316793, 0.046033762, 0.0447623, + 0.043502413, 0.042254124, 0.041017443, 0.039792392, + 0.038578995, 0.037377283, 0.036187284, 0.035009038, + 0.033842582, 0.032687962, 0.031545233, 0.030414443, 0.02929566, + 0.02818895, 0.027094385, 0.026012046, 0.024942026, 0.023884421, + 0.022839336, 0.021806888, 0.020787204, 0.019780423, 0.0187867, + 0.0178062, 0.016839107, 0.015885621, 0.014945968, 0.014020392, + 0.013109165, 0.012212592, 0.011331013, 0.01046481, 0.009614414, + 0.008780315, 0.007963077, 0.0071633533, 0.006381906, + 0.0056196423, 0.0048776558, 0.004157295, 0.0034602648, + 0.0027887989, 0.0021459677, 0.0015362998, 0.0009672693, + 0.00045413437, +} diff --git a/contrib/go/_std_1.18/src/math/rand/normal.go b/contrib/go/_std_1.18/src/math/rand/normal.go new file mode 100644 index 0000000000..2c5a7aa99b --- /dev/null +++ b/contrib/go/_std_1.18/src/math/rand/normal.go @@ -0,0 +1,157 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package rand + +import ( + "math" +) + +/* + * Normal distribution + * + * See "The Ziggurat Method for Generating Random Variables" + * (Marsaglia & Tsang, 2000) + * http://www.jstatsoft.org/v05/i08/paper [pdf] + */ + +const ( + rn = 3.442619855899 +) + +func absInt32(i int32) uint32 { + if i < 0 { + return uint32(-i) + } + return uint32(i) +} + +// NormFloat64 returns a normally distributed float64 in +// the range -math.MaxFloat64 through +math.MaxFloat64 inclusive, +// with standard normal distribution (mean = 0, stddev = 1). +// To produce a different normal distribution, callers can +// adjust the output using: +// +// sample = NormFloat64() * desiredStdDev + desiredMean +// +func (r *Rand) NormFloat64() float64 { + for { + j := int32(r.Uint32()) // Possibly negative + i := j & 0x7F + x := float64(j) * float64(wn[i]) + if absInt32(j) < kn[i] { + // This case should be hit better than 99% of the time. + return x + } + + if i == 0 { + // This extra work is only required for the base strip. + for { + x = -math.Log(r.Float64()) * (1.0 / rn) + y := -math.Log(r.Float64()) + if y+y >= x*x { + break + } + } + if j > 0 { + return rn + x + } + return -rn - x + } + if fn[i]+float32(r.Float64())*(fn[i-1]-fn[i]) < float32(math.Exp(-.5*x*x)) { + return x + } + } +} + +var kn = [128]uint32{ + 0x76ad2212, 0x0, 0x600f1b53, 0x6ce447a6, 0x725b46a2, + 0x7560051d, 0x774921eb, 0x789a25bd, 0x799045c3, 0x7a4bce5d, + 0x7adf629f, 0x7b5682a6, 0x7bb8a8c6, 0x7c0ae722, 0x7c50cce7, + 0x7c8cec5b, 0x7cc12cd6, 0x7ceefed2, 0x7d177e0b, 0x7d3b8883, + 0x7d5bce6c, 0x7d78dd64, 0x7d932886, 0x7dab0e57, 0x7dc0dd30, + 0x7dd4d688, 0x7de73185, 0x7df81cea, 0x7e07c0a3, 0x7e163efa, + 0x7e23b587, 0x7e303dfd, 0x7e3beec2, 0x7e46db77, 0x7e51155d, + 0x7e5aabb3, 0x7e63abf7, 0x7e6c222c, 0x7e741906, 0x7e7b9a18, + 0x7e82adfa, 0x7e895c63, 0x7e8fac4b, 0x7e95a3fb, 0x7e9b4924, + 0x7ea0a0ef, 0x7ea5b00d, 0x7eaa7ac3, 0x7eaf04f3, 0x7eb3522a, + 0x7eb765a5, 0x7ebb4259, 0x7ebeeafd, 0x7ec2620a, 0x7ec5a9c4, + 0x7ec8c441, 0x7ecbb365, 0x7ece78ed, 0x7ed11671, 0x7ed38d62, + 0x7ed5df12, 0x7ed80cb4, 0x7eda175c, 0x7edc0005, 0x7eddc78e, + 0x7edf6ebf, 0x7ee0f647, 0x7ee25ebe, 0x7ee3a8a9, 0x7ee4d473, + 0x7ee5e276, 0x7ee6d2f5, 0x7ee7a620, 0x7ee85c10, 0x7ee8f4cd, + 0x7ee97047, 0x7ee9ce59, 0x7eea0eca, 0x7eea3147, 0x7eea3568, + 0x7eea1aab, 0x7ee9e071, 0x7ee98602, 0x7ee90a88, 0x7ee86d08, + 0x7ee7ac6a, 0x7ee6c769, 0x7ee5bc9c, 0x7ee48a67, 0x7ee32efc, + 0x7ee1a857, 0x7edff42f, 0x7ede0ffa, 0x7edbf8d9, 0x7ed9ab94, + 0x7ed7248d, 0x7ed45fae, 0x7ed1585c, 0x7ece095f, 0x7eca6ccb, + 0x7ec67be2, 0x7ec22eee, 0x7ebd7d1a, 0x7eb85c35, 0x7eb2c075, + 0x7eac9c20, 0x7ea5df27, 0x7e9e769f, 0x7e964c16, 0x7e8d44ba, + 0x7e834033, 0x7e781728, 0x7e6b9933, 0x7e5d8a1a, 0x7e4d9ded, + 0x7e3b737a, 0x7e268c2f, 0x7e0e3ff5, 0x7df1aa5d, 0x7dcf8c72, + 0x7da61a1e, 0x7d72a0fb, 0x7d30e097, 0x7cd9b4ab, 0x7c600f1a, + 0x7ba90bdc, 0x7a722176, 0x77d664e5, +} +var wn = [128]float32{ + 1.7290405e-09, 1.2680929e-10, 1.6897518e-10, 1.9862688e-10, + 2.2232431e-10, 2.4244937e-10, 2.601613e-10, 2.7611988e-10, + 2.9073963e-10, 3.042997e-10, 3.1699796e-10, 3.289802e-10, + 3.4035738e-10, 3.5121603e-10, 3.616251e-10, 3.7164058e-10, + 3.8130857e-10, 3.9066758e-10, 3.9975012e-10, 4.08584e-10, + 4.1719309e-10, 4.2559822e-10, 4.338176e-10, 4.418672e-10, + 4.497613e-10, 4.5751258e-10, 4.651324e-10, 4.7263105e-10, + 4.8001775e-10, 4.87301e-10, 4.944885e-10, 5.015873e-10, + 5.0860405e-10, 5.155446e-10, 5.2241467e-10, 5.2921934e-10, + 5.359635e-10, 5.426517e-10, 5.4928817e-10, 5.5587696e-10, + 5.624219e-10, 5.6892646e-10, 5.753941e-10, 5.818282e-10, + 5.882317e-10, 5.946077e-10, 6.00959e-10, 6.072884e-10, + 6.135985e-10, 6.19892e-10, 6.2617134e-10, 6.3243905e-10, + 6.386974e-10, 6.449488e-10, 6.511956e-10, 6.5744005e-10, + 6.6368433e-10, 6.699307e-10, 6.7618144e-10, 6.824387e-10, + 6.8870465e-10, 6.949815e-10, 7.012715e-10, 7.075768e-10, + 7.1389966e-10, 7.202424e-10, 7.266073e-10, 7.329966e-10, + 7.394128e-10, 7.4585826e-10, 7.5233547e-10, 7.58847e-10, + 7.653954e-10, 7.719835e-10, 7.7861395e-10, 7.852897e-10, + 7.920138e-10, 7.987892e-10, 8.0561924e-10, 8.125073e-10, + 8.194569e-10, 8.2647167e-10, 8.3355556e-10, 8.407127e-10, + 8.479473e-10, 8.55264e-10, 8.6266755e-10, 8.7016316e-10, + 8.777562e-10, 8.8545243e-10, 8.932582e-10, 9.0117996e-10, + 9.09225e-10, 9.174008e-10, 9.2571584e-10, 9.341788e-10, + 9.427997e-10, 9.515889e-10, 9.605579e-10, 9.697193e-10, + 9.790869e-10, 9.88676e-10, 9.985036e-10, 1.0085882e-09, + 1.0189509e-09, 1.0296151e-09, 1.0406069e-09, 1.0519566e-09, + 1.063698e-09, 1.0758702e-09, 1.0885183e-09, 1.1016947e-09, + 1.1154611e-09, 1.1298902e-09, 1.1450696e-09, 1.1611052e-09, + 1.1781276e-09, 1.1962995e-09, 1.2158287e-09, 1.2369856e-09, + 1.2601323e-09, 1.2857697e-09, 1.3146202e-09, 1.347784e-09, + 1.3870636e-09, 1.4357403e-09, 1.5008659e-09, 1.6030948e-09, +} +var fn = [128]float32{ + 1, 0.9635997, 0.9362827, 0.9130436, 0.89228165, 0.87324303, + 0.8555006, 0.8387836, 0.8229072, 0.8077383, 0.793177, + 0.7791461, 0.7655842, 0.7524416, 0.73967725, 0.7272569, + 0.7151515, 0.7033361, 0.69178915, 0.68049186, 0.6694277, + 0.658582, 0.6479418, 0.63749546, 0.6272325, 0.6171434, + 0.6072195, 0.5974532, 0.58783704, 0.5783647, 0.56903, + 0.5598274, 0.5507518, 0.54179835, 0.5329627, 0.52424055, + 0.5156282, 0.50712204, 0.49871865, 0.49041483, 0.48220766, + 0.4740943, 0.46607214, 0.4581387, 0.45029163, 0.44252872, + 0.43484783, 0.427247, 0.41972435, 0.41227803, 0.40490642, + 0.39760786, 0.3903808, 0.3832238, 0.37613547, 0.36911446, + 0.3621595, 0.35526937, 0.34844297, 0.34167916, 0.33497685, + 0.3283351, 0.3217529, 0.3152294, 0.30876362, 0.30235484, + 0.29600215, 0.28970486, 0.2834622, 0.2772735, 0.27113807, + 0.2650553, 0.25902456, 0.2530453, 0.24711695, 0.241239, + 0.23541094, 0.22963232, 0.2239027, 0.21822165, 0.21258877, + 0.20700371, 0.20146611, 0.19597565, 0.19053204, 0.18513499, + 0.17978427, 0.17447963, 0.1692209, 0.16400786, 0.15884037, + 0.15371831, 0.14864157, 0.14361008, 0.13862377, 0.13368265, + 0.12878671, 0.12393598, 0.119130544, 0.11437051, 0.10965602, + 0.104987256, 0.10036444, 0.095787846, 0.0912578, 0.08677467, + 0.0823389, 0.077950984, 0.073611505, 0.06932112, 0.06508058, + 0.06089077, 0.056752663, 0.0526674, 0.048636295, 0.044660863, + 0.040742867, 0.03688439, 0.033087887, 0.029356318, + 0.025693292, 0.022103304, 0.018592102, 0.015167298, + 0.011839478, 0.008624485, 0.005548995, 0.0026696292, +} diff --git a/contrib/go/_std_1.18/src/math/rand/rand.go b/contrib/go/_std_1.18/src/math/rand/rand.go new file mode 100644 index 0000000000..13f20ca5ef --- /dev/null +++ b/contrib/go/_std_1.18/src/math/rand/rand.go @@ -0,0 +1,421 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package rand implements pseudo-random number generators unsuitable for +// security-sensitive work. +// +// Random numbers are generated by a Source. Top-level functions, such as +// Float64 and Int, use a default shared Source that produces a deterministic +// sequence of values each time a program is run. Use the Seed function to +// initialize the default Source if different behavior is required for each run. +// The default Source is safe for concurrent use by multiple goroutines, but +// Sources created by NewSource are not. +// +// This package's outputs might be easily predictable regardless of how it's +// seeded. For random numbers suitable for security-sensitive work, see the +// crypto/rand package. +package rand + +import "sync" + +// A Source represents a source of uniformly-distributed +// pseudo-random int64 values in the range [0, 1<<63). +type Source interface { + Int63() int64 + Seed(seed int64) +} + +// A Source64 is a Source that can also generate +// uniformly-distributed pseudo-random uint64 values in +// the range [0, 1<<64) directly. +// If a Rand r's underlying Source s implements Source64, +// then r.Uint64 returns the result of one call to s.Uint64 +// instead of making two calls to s.Int63. +type Source64 interface { + Source + Uint64() uint64 +} + +// NewSource returns a new pseudo-random Source seeded with the given value. +// Unlike the default Source used by top-level functions, this source is not +// safe for concurrent use by multiple goroutines. +func NewSource(seed int64) Source { + var rng rngSource + rng.Seed(seed) + return &rng +} + +// A Rand is a source of random numbers. +type Rand struct { + src Source + s64 Source64 // non-nil if src is source64 + + // readVal contains remainder of 63-bit integer used for bytes + // generation during most recent Read call. + // It is saved so next Read call can start where the previous + // one finished. + readVal int64 + // readPos indicates the number of low-order bytes of readVal + // that are still valid. + readPos int8 +} + +// New returns a new Rand that uses random values from src +// to generate other random values. +func New(src Source) *Rand { + s64, _ := src.(Source64) + return &Rand{src: src, s64: s64} +} + +// Seed uses the provided seed value to initialize the generator to a deterministic state. +// Seed should not be called concurrently with any other Rand method. +func (r *Rand) Seed(seed int64) { + if lk, ok := r.src.(*lockedSource); ok { + lk.seedPos(seed, &r.readPos) + return + } + + r.src.Seed(seed) + r.readPos = 0 +} + +// Int63 returns a non-negative pseudo-random 63-bit integer as an int64. +func (r *Rand) Int63() int64 { return r.src.Int63() } + +// Uint32 returns a pseudo-random 32-bit value as a uint32. +func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) } + +// Uint64 returns a pseudo-random 64-bit value as a uint64. +func (r *Rand) Uint64() uint64 { + if r.s64 != nil { + return r.s64.Uint64() + } + return uint64(r.Int63())>>31 | uint64(r.Int63())<<32 +} + +// Int31 returns a non-negative pseudo-random 31-bit integer as an int32. +func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) } + +// Int returns a non-negative pseudo-random int. +func (r *Rand) Int() int { + u := uint(r.Int63()) + return int(u << 1 >> 1) // clear sign bit if int == int32 +} + +// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n). +// It panics if n <= 0. +func (r *Rand) Int63n(n int64) int64 { + if n <= 0 { + panic("invalid argument to Int63n") + } + if n&(n-1) == 0 { // n is power of two, can mask + return r.Int63() & (n - 1) + } + max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) + v := r.Int63() + for v > max { + v = r.Int63() + } + return v % n +} + +// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n). +// It panics if n <= 0. +func (r *Rand) Int31n(n int32) int32 { + if n <= 0 { + panic("invalid argument to Int31n") + } + if n&(n-1) == 0 { // n is power of two, can mask + return r.Int31() & (n - 1) + } + max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) + v := r.Int31() + for v > max { + v = r.Int31() + } + return v % n +} + +// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n). +// n must be > 0, but int31n does not check this; the caller must ensure it. +// int31n exists because Int31n is inefficient, but Go 1 compatibility +// requires that the stream of values produced by math/rand remain unchanged. +// int31n can thus only be used internally, by newly introduced APIs. +// +// For implementation details, see: +// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction +// https://lemire.me/blog/2016/06/30/fast-random-shuffling +func (r *Rand) int31n(n int32) int32 { + v := r.Uint32() + prod := uint64(v) * uint64(n) + low := uint32(prod) + if low < uint32(n) { + thresh := uint32(-n) % uint32(n) + for low < thresh { + v = r.Uint32() + prod = uint64(v) * uint64(n) + low = uint32(prod) + } + } + return int32(prod >> 32) +} + +// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n). +// It panics if n <= 0. +func (r *Rand) Intn(n int) int { + if n <= 0 { + panic("invalid argument to Intn") + } + if n <= 1<<31-1 { + return int(r.Int31n(int32(n))) + } + return int(r.Int63n(int64(n))) +} + +// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0). +func (r *Rand) Float64() float64 { + // A clearer, simpler implementation would be: + // return float64(r.Int63n(1<<53)) / (1<<53) + // However, Go 1 shipped with + // return float64(r.Int63()) / (1 << 63) + // and we want to preserve that value stream. + // + // There is one bug in the value stream: r.Int63() may be so close + // to 1<<63 that the division rounds up to 1.0, and we've guaranteed + // that the result is always less than 1.0. + // + // We tried to fix this by mapping 1.0 back to 0.0, but since float64 + // values near 0 are much denser than near 1, mapping 1 to 0 caused + // a theoretically significant overshoot in the probability of returning 0. + // Instead of that, if we round up to 1, just try again. + // Getting 1 only happens 1/2⁵³ of the time, so most clients + // will not observe it anyway. +again: + f := float64(r.Int63()) / (1 << 63) + if f == 1 { + goto again // resample; this branch is taken O(never) + } + return f +} + +// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0). +func (r *Rand) Float32() float32 { + // Same rationale as in Float64: we want to preserve the Go 1 value + // stream except we want to fix it not to return 1.0 + // This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Float64). +again: + f := float32(r.Float64()) + if f == 1 { + goto again // resample; this branch is taken O(very rarely) + } + return f +} + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers +// in the half-open interval [0,n). +func (r *Rand) Perm(n int) []int { + m := make([]int, n) + // In the following loop, the iteration when i=0 always swaps m[0] with m[0]. + // A change to remove this useless iteration is to assign 1 to i in the init + // statement. But Perm also effects r. Making this change will affect + // the final state of r. So this change can't be made for compatibility + // reasons for Go 1. + for i := 0; i < n; i++ { + j := r.Intn(i + 1) + m[i] = m[j] + m[j] = i + } + return m +} + +// Shuffle pseudo-randomizes the order of elements. +// n is the number of elements. Shuffle panics if n < 0. +// swap swaps the elements with indexes i and j. +func (r *Rand) Shuffle(n int, swap func(i, j int)) { + if n < 0 { + panic("invalid argument to Shuffle") + } + + // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + // Shuffle really ought not be called with n that doesn't fit in 32 bits. + // Not only will it take a very long time, but with 2³¹! possible permutations, + // there's no way that any PRNG can have a big enough internal state to + // generate even a minuscule percentage of the possible permutations. + // Nevertheless, the right API signature accepts an int n, so handle it as best we can. + i := n - 1 + for ; i > 1<<31-1-1; i-- { + j := int(r.Int63n(int64(i + 1))) + swap(i, j) + } + for ; i > 0; i-- { + j := int(r.int31n(int32(i + 1))) + swap(i, j) + } +} + +// Read generates len(p) random bytes and writes them into p. It +// always returns len(p) and a nil error. +// Read should not be called concurrently with any other Rand method. +func (r *Rand) Read(p []byte) (n int, err error) { + if lk, ok := r.src.(*lockedSource); ok { + return lk.read(p, &r.readVal, &r.readPos) + } + return read(p, r.src, &r.readVal, &r.readPos) +} + +func read(p []byte, src Source, readVal *int64, readPos *int8) (n int, err error) { + pos := *readPos + val := *readVal + rng, _ := src.(*rngSource) + for n = 0; n < len(p); n++ { + if pos == 0 { + if rng != nil { + val = rng.Int63() + } else { + val = src.Int63() + } + pos = 7 + } + p[n] = byte(val) + val >>= 8 + pos-- + } + *readPos = pos + *readVal = val + return +} + +/* + * Top-level convenience functions + */ + +var globalRand = New(&lockedSource{src: NewSource(1).(*rngSource)}) + +// Type assert that globalRand's source is a lockedSource whose src is a *rngSource. +var _ *rngSource = globalRand.src.(*lockedSource).src + +// Seed uses the provided seed value to initialize the default Source to a +// deterministic state. If Seed is not called, the generator behaves as +// if seeded by Seed(1). Seed values that have the same remainder when +// divided by 2³¹-1 generate the same pseudo-random sequence. +// Seed, unlike the Rand.Seed method, is safe for concurrent use. +func Seed(seed int64) { globalRand.Seed(seed) } + +// Int63 returns a non-negative pseudo-random 63-bit integer as an int64 +// from the default Source. +func Int63() int64 { return globalRand.Int63() } + +// Uint32 returns a pseudo-random 32-bit value as a uint32 +// from the default Source. +func Uint32() uint32 { return globalRand.Uint32() } + +// Uint64 returns a pseudo-random 64-bit value as a uint64 +// from the default Source. +func Uint64() uint64 { return globalRand.Uint64() } + +// Int31 returns a non-negative pseudo-random 31-bit integer as an int32 +// from the default Source. +func Int31() int32 { return globalRand.Int31() } + +// Int returns a non-negative pseudo-random int from the default Source. +func Int() int { return globalRand.Int() } + +// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n) +// from the default Source. +// It panics if n <= 0. +func Int63n(n int64) int64 { return globalRand.Int63n(n) } + +// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n) +// from the default Source. +// It panics if n <= 0. +func Int31n(n int32) int32 { return globalRand.Int31n(n) } + +// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n) +// from the default Source. +// It panics if n <= 0. +func Intn(n int) int { return globalRand.Intn(n) } + +// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0) +// from the default Source. +func Float64() float64 { return globalRand.Float64() } + +// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0) +// from the default Source. +func Float32() float32 { return globalRand.Float32() } + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers +// in the half-open interval [0,n) from the default Source. +func Perm(n int) []int { return globalRand.Perm(n) } + +// Shuffle pseudo-randomizes the order of elements using the default Source. +// n is the number of elements. Shuffle panics if n < 0. +// swap swaps the elements with indexes i and j. +func Shuffle(n int, swap func(i, j int)) { globalRand.Shuffle(n, swap) } + +// Read generates len(p) random bytes from the default Source and +// writes them into p. It always returns len(p) and a nil error. +// Read, unlike the Rand.Read method, is safe for concurrent use. +func Read(p []byte) (n int, err error) { return globalRand.Read(p) } + +// NormFloat64 returns a normally distributed float64 in the range +// [-math.MaxFloat64, +math.MaxFloat64] with +// standard normal distribution (mean = 0, stddev = 1) +// from the default Source. +// To produce a different normal distribution, callers can +// adjust the output using: +// +// sample = NormFloat64() * desiredStdDev + desiredMean +// +func NormFloat64() float64 { return globalRand.NormFloat64() } + +// ExpFloat64 returns an exponentially distributed float64 in the range +// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter +// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source. +// To produce a distribution with a different rate parameter, +// callers can adjust the output using: +// +// sample = ExpFloat64() / desiredRateParameter +// +func ExpFloat64() float64 { return globalRand.ExpFloat64() } + +type lockedSource struct { + lk sync.Mutex + src *rngSource +} + +func (r *lockedSource) Int63() (n int64) { + r.lk.Lock() + n = r.src.Int63() + r.lk.Unlock() + return +} + +func (r *lockedSource) Uint64() (n uint64) { + r.lk.Lock() + n = r.src.Uint64() + r.lk.Unlock() + return +} + +func (r *lockedSource) Seed(seed int64) { + r.lk.Lock() + r.src.Seed(seed) + r.lk.Unlock() +} + +// seedPos implements Seed for a lockedSource without a race condition. +func (r *lockedSource) seedPos(seed int64, readPos *int8) { + r.lk.Lock() + r.src.Seed(seed) + *readPos = 0 + r.lk.Unlock() +} + +// read implements Read for a lockedSource without a race condition. +func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) { + r.lk.Lock() + n, err = read(p, r.src, readVal, readPos) + r.lk.Unlock() + return +} diff --git a/contrib/go/_std_1.18/src/math/rand/rng.go b/contrib/go/_std_1.18/src/math/rand/rng.go new file mode 100644 index 0000000000..f305df1a20 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/rand/rng.go @@ -0,0 +1,252 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package rand + +/* + * Uniform distribution + * + * algorithm by + * DP Mitchell and JA Reeds + */ + +const ( + rngLen = 607 + rngTap = 273 + rngMax = 1 << 63 + rngMask = rngMax - 1 + int32max = (1 << 31) - 1 +) + +var ( + // rngCooked used for seeding. See gen_cooked.go for details. + rngCooked [rngLen]int64 = [...]int64{ + -4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259, + -6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721, + 7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764, + 4593015457530856296, 8140875735541888011, -5903942795589686782, -603556388664454774, + -7496297993371156308, 113108499721038619, 4569519971459345583, -4160538177779461077, + -6835753265595711384, -6507240692498089696, 6559392774825876886, 7650093201692370310, + 7684323884043752161, -8965504200858744418, -2629915517445760644, 271327514973697897, + -6433985589514657524, 1065192797246149621, 3344507881999356393, -4763574095074709175, + 7465081662728599889, 1014950805555097187, -4773931307508785033, -5742262670416273165, + 2418672789110888383, 5796562887576294778, 4484266064449540171, 3738982361971787048, + -4699774852342421385, 10530508058128498, -589538253572429690, -6598062107225984180, + 8660405965245884302, 10162832508971942, -2682657355892958417, 7031802312784620857, + 6240911277345944669, 831864355460801054, -1218937899312622917, 2116287251661052151, + 2202309800992166967, 9161020366945053561, 4069299552407763864, 4936383537992622449, + 457351505131524928, -8881176990926596454, -6375600354038175299, -7155351920868399290, + 4368649989588021065, 887231587095185257, -3659780529968199312, -2407146836602825512, + 5616972787034086048, -751562733459939242, 1686575021641186857, -5177887698780513806, + -4979215821652996885, -1375154703071198421, 5632136521049761902, -8390088894796940536, + -193645528485698615, -5979788902190688516, -4907000935050298721, -285522056888777828, + -2776431630044341707, 1679342092332374735, 6050638460742422078, -2229851317345194226, + -1582494184340482199, 5881353426285907985, 812786550756860885, 4541845584483343330, + -6497901820577766722, 4980675660146853729, -4012602956251539747, -329088717864244987, + -2896929232104691526, 1495812843684243920, -2153620458055647789, 7370257291860230865, + -2466442761497833547, 4706794511633873654, -1398851569026877145, 8549875090542453214, + -9189721207376179652, -7894453601103453165, 7297902601803624459, 1011190183918857495, + -6985347000036920864, 5147159997473910359, -8326859945294252826, 2659470849286379941, + 6097729358393448602, -7491646050550022124, -5117116194870963097, -896216826133240300, + -745860416168701406, 5803876044675762232, -787954255994554146, -3234519180203704564, + -4507534739750823898, -1657200065590290694, 505808562678895611, -4153273856159712438, + -8381261370078904295, 572156825025677802, 1791881013492340891, 3393267094866038768, + -5444650186382539299, 2352769483186201278, -7930912453007408350, -325464993179687389, + -3441562999710612272, -6489413242825283295, 5092019688680754699, -227247482082248967, + 4234737173186232084, 5027558287275472836, 4635198586344772304, -536033143587636457, + 5907508150730407386, -8438615781380831356, 972392927514829904, -3801314342046600696, + -4064951393885491917, -174840358296132583, 2407211146698877100, -1640089820333676239, + 3940796514530962282, -5882197405809569433, 3095313889586102949, -1818050141166537098, + 5832080132947175283, 7890064875145919662, 8184139210799583195, -8073512175445549678, + -7758774793014564506, -4581724029666783935, 3516491885471466898, -8267083515063118116, + 6657089965014657519, 5220884358887979358, 1796677326474620641, 5340761970648932916, + 1147977171614181568, 5066037465548252321, 2574765911837859848, 1085848279845204775, + -5873264506986385449, 6116438694366558490, 2107701075971293812, -7420077970933506541, + 2469478054175558874, -1855128755834809824, -5431463669011098282, -9038325065738319171, + -6966276280341336160, 7217693971077460129, -8314322083775271549, 7196649268545224266, + -3585711691453906209, -5267827091426810625, 8057528650917418961, -5084103596553648165, + -2601445448341207749, -7850010900052094367, 6527366231383600011, 3507654575162700890, + 9202058512774729859, 1954818376891585542, -2582991129724600103, 8299563319178235687, + -5321504681635821435, 7046310742295574065, -2376176645520785576, -7650733936335907755, + 8850422670118399721, 3631909142291992901, 5158881091950831288, -6340413719511654215, + 4763258931815816403, 6280052734341785344, -4979582628649810958, 2043464728020827976, + -2678071570832690343, 4562580375758598164, 5495451168795427352, -7485059175264624713, + 553004618757816492, 6895160632757959823, -989748114590090637, 7139506338801360852, + -672480814466784139, 5535668688139305547, 2430933853350256242, -3821430778991574732, + -1063731997747047009, -3065878205254005442, 7632066283658143750, 6308328381617103346, + 3681878764086140361, 3289686137190109749, 6587997200611086848, 244714774258135476, + -5143583659437639708, 8090302575944624335, 2945117363431356361, -8359047641006034763, + 3009039260312620700, -793344576772241777, 401084700045993341, -1968749590416080887, + 4707864159563588614, -3583123505891281857, -3240864324164777915, -5908273794572565703, + -3719524458082857382, -5281400669679581926, 8118566580304798074, 3839261274019871296, + 7062410411742090847, -8481991033874568140, 6027994129690250817, -6725542042704711878, + -2971981702428546974, -7854441788951256975, 8809096399316380241, 6492004350391900708, + 2462145737463489636, -8818543617934476634, -5070345602623085213, -8961586321599299868, + -3758656652254704451, -8630661632476012791, 6764129236657751224, -709716318315418359, + -3403028373052861600, -8838073512170985897, -3999237033416576341, -2920240395515973663, + -2073249475545404416, 368107899140673753, -6108185202296464250, -6307735683270494757, + 4782583894627718279, 6718292300699989587, 8387085186914375220, 3387513132024756289, + 4654329375432538231, -292704475491394206, -3848998599978456535, 7623042350483453954, + 7725442901813263321, 9186225467561587250, -5132344747257272453, -6865740430362196008, + 2530936820058611833, 1636551876240043639, -3658707362519810009, 1452244145334316253, + -7161729655835084979, -7943791770359481772, 9108481583171221009, -3200093350120725999, + 5007630032676973346, 2153168792952589781, 6720334534964750538, -3181825545719981703, + 3433922409283786309, 2285479922797300912, 3110614940896576130, -2856812446131932915, + -3804580617188639299, 7163298419643543757, 4891138053923696990, 580618510277907015, + 1684034065251686769, 4429514767357295841, -8893025458299325803, -8103734041042601133, + 7177515271653460134, 4589042248470800257, -1530083407795771245, 143607045258444228, + 246994305896273627, -8356954712051676521, 6473547110565816071, 3092379936208876896, + 2058427839513754051, -4089587328327907870, 8785882556301281247, -3074039370013608197, + -637529855400303673, 6137678347805511274, -7152924852417805802, 5708223427705576541, + -3223714144396531304, 4358391411789012426, 325123008708389849, 6837621693887290924, + 4843721905315627004, -3212720814705499393, -3825019837890901156, 4602025990114250980, + 1044646352569048800, 9106614159853161675, -8394115921626182539, -4304087667751778808, + 2681532557646850893, 3681559472488511871, -3915372517896561773, -2889241648411946534, + -6564663803938238204, -8060058171802589521, 581945337509520675, 3648778920718647903, + -4799698790548231394, -7602572252857820065, 220828013409515943, -1072987336855386047, + 4287360518296753003, -4633371852008891965, 5513660857261085186, -2258542936462001533, + -8744380348503999773, 8746140185685648781, 228500091334420247, 1356187007457302238, + 3019253992034194581, 3152601605678500003, -8793219284148773595, 5559581553696971176, + 4916432985369275664, -8559797105120221417, -5802598197927043732, 2868348622579915573, + -7224052902810357288, -5894682518218493085, 2587672709781371173, -7706116723325376475, + 3092343956317362483, -5561119517847711700, 972445599196498113, -1558506600978816441, + 1708913533482282562, -2305554874185907314, -6005743014309462908, -6653329009633068701, + -483583197311151195, 2488075924621352812, -4529369641467339140, -4663743555056261452, + 2997203966153298104, 1282559373026354493, 240113143146674385, 8665713329246516443, + 628141331766346752, -4651421219668005332, -7750560848702540400, 7596648026010355826, + -3132152619100351065, 7834161864828164065, 7103445518877254909, 4390861237357459201, + -4780718172614204074, -319889632007444440, 622261699494173647, -3186110786557562560, + -8718967088789066690, -1948156510637662747, -8212195255998774408, -7028621931231314745, + 2623071828615234808, -4066058308780939700, -5484966924888173764, -6683604512778046238, + -6756087640505506466, 5256026990536851868, 7841086888628396109, 6640857538655893162, + -8021284697816458310, -7109857044414059830, -1689021141511844405, -4298087301956291063, + -4077748265377282003, -998231156719803476, 2719520354384050532, 9132346697815513771, + 4332154495710163773, -2085582442760428892, 6994721091344268833, -2556143461985726874, + -8567931991128098309, 59934747298466858, -3098398008776739403, -265597256199410390, + 2332206071942466437, -7522315324568406181, 3154897383618636503, -7585605855467168281, + -6762850759087199275, 197309393502684135, -8579694182469508493, 2543179307861934850, + 4350769010207485119, -4468719947444108136, -7207776534213261296, -1224312577878317200, + 4287946071480840813, 8362686366770308971, 6486469209321732151, -5605644191012979782, + -1669018511020473564, 4450022655153542367, -7618176296641240059, -3896357471549267421, + -4596796223304447488, -6531150016257070659, -8982326463137525940, -4125325062227681798, + -1306489741394045544, -8338554946557245229, 5329160409530630596, 7790979528857726136, + 4955070238059373407, -4304834761432101506, -6215295852904371179, 3007769226071157901, + -6753025801236972788, 8928702772696731736, 7856187920214445904, -4748497451462800923, + 7900176660600710914, -7082800908938549136, -6797926979589575837, -6737316883512927978, + 4186670094382025798, 1883939007446035042, -414705992779907823, 3734134241178479257, + 4065968871360089196, 6953124200385847784, -7917685222115876751, -7585632937840318161, + -5567246375906782599, -5256612402221608788, 3106378204088556331, -2894472214076325998, + 4565385105440252958, 1979884289539493806, -6891578849933910383, 3783206694208922581, + 8464961209802336085, 2843963751609577687, 3030678195484896323, -4429654462759003204, + 4459239494808162889, 402587895800087237, 8057891408711167515, 4541888170938985079, + 1042662272908816815, -3666068979732206850, 2647678726283249984, 2144477441549833761, + -3417019821499388721, -2105601033380872185, 5916597177708541638, -8760774321402454447, + 8833658097025758785, 5970273481425315300, 563813119381731307, -6455022486202078793, + 1598828206250873866, -4016978389451217698, -2988328551145513985, -6071154634840136312, + 8469693267274066490, 125672920241807416, -3912292412830714870, -2559617104544284221, + -486523741806024092, -4735332261862713930, 5923302823487327109, -9082480245771672572, + -1808429243461201518, 7990420780896957397, 4317817392807076702, 3625184369705367340, + -6482649271566653105, -3480272027152017464, -3225473396345736649, -368878695502291645, + -3981164001421868007, -8522033136963788610, 7609280429197514109, 3020985755112334161, + -2572049329799262942, 2635195723621160615, 5144520864246028816, -8188285521126945980, + 1567242097116389047, 8172389260191636581, -2885551685425483535, -7060359469858316883, + -6480181133964513127, -7317004403633452381, 6011544915663598137, 5932255307352610768, + 2241128460406315459, -8327867140638080220, 3094483003111372717, 4583857460292963101, + 9079887171656594975, -384082854924064405, -3460631649611717935, 4225072055348026230, + -7385151438465742745, 3801620336801580414, -399845416774701952, -7446754431269675473, + 7899055018877642622, 5421679761463003041, 5521102963086275121, -4975092593295409910, + 8735487530905098534, -7462844945281082830, -2080886987197029914, -1000715163927557685, + -4253840471931071485, -5828896094657903328, 6424174453260338141, 359248545074932887, + -5949720754023045210, -2426265837057637212, 3030918217665093212, -9077771202237461772, + -3186796180789149575, 740416251634527158, -2142944401404840226, 6951781370868335478, + 399922722363687927, -8928469722407522623, -1378421100515597285, -8343051178220066766, + -3030716356046100229, -8811767350470065420, 9026808440365124461, 6440783557497587732, + 4615674634722404292, 539897290441580544, 2096238225866883852, 8751955639408182687, + -7316147128802486205, 7381039757301768559, 6157238513393239656, -1473377804940618233, + 8629571604380892756, 5280433031239081479, 7101611890139813254, 2479018537985767835, + 7169176924412769570, -1281305539061572506, -7865612307799218120, 2278447439451174845, + 3625338785743880657, 6477479539006708521, 8976185375579272206, -3712000482142939688, + 1326024180520890843, 7537449876596048829, 5464680203499696154, 3189671183162196045, + 6346751753565857109, -8982212049534145501, -6127578587196093755, -245039190118465649, + -6320577374581628592, 7208698530190629697, 7276901792339343736, -7490986807540332668, + 4133292154170828382, 2918308698224194548, -7703910638917631350, -3929437324238184044, + -4300543082831323144, -6344160503358350167, 5896236396443472108, -758328221503023383, + -1894351639983151068, -307900319840287220, -6278469401177312761, -2171292963361310674, + 8382142935188824023, 9103922860780351547, 4152330101494654406, + } +) + +type rngSource struct { + tap int // index into vec + feed int // index into vec + vec [rngLen]int64 // current feedback register +} + +// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1) +func seedrand(x int32) int32 { + const ( + A = 48271 + Q = 44488 + R = 3399 + ) + + hi := x / Q + lo := x % Q + x = A*lo - R*hi + if x < 0 { + x += int32max + } + return x +} + +// Seed uses the provided seed value to initialize the generator to a deterministic state. +func (rng *rngSource) Seed(seed int64) { + rng.tap = 0 + rng.feed = rngLen - rngTap + + seed = seed % int32max + if seed < 0 { + seed += int32max + } + if seed == 0 { + seed = 89482311 + } + + x := int32(seed) + for i := -20; i < rngLen; i++ { + x = seedrand(x) + if i >= 0 { + var u int64 + u = int64(x) << 40 + x = seedrand(x) + u ^= int64(x) << 20 + x = seedrand(x) + u ^= int64(x) + u ^= rngCooked[i] + rng.vec[i] = u + } + } +} + +// Int63 returns a non-negative pseudo-random 63-bit integer as an int64. +func (rng *rngSource) Int63() int64 { + return int64(rng.Uint64() & rngMask) +} + +// Uint64 returns a non-negative pseudo-random 64-bit integer as an uint64. +func (rng *rngSource) Uint64() uint64 { + rng.tap-- + if rng.tap < 0 { + rng.tap += rngLen + } + + rng.feed-- + if rng.feed < 0 { + rng.feed += rngLen + } + + x := rng.vec[rng.feed] + rng.vec[rng.tap] + rng.vec[rng.feed] = x + return uint64(x) +} diff --git a/contrib/go/_std_1.18/src/math/rand/zipf.go b/contrib/go/_std_1.18/src/math/rand/zipf.go new file mode 100644 index 0000000000..f04c814eb7 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/rand/zipf.go @@ -0,0 +1,77 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// W.Hormann, G.Derflinger: +// "Rejection-Inversion to Generate Variates +// from Monotone Discrete Distributions" +// http://eeyore.wu-wien.ac.at/papers/96-04-04.wh-der.ps.gz + +package rand + +import "math" + +// A Zipf generates Zipf distributed variates. +type Zipf struct { + r *Rand + imax float64 + v float64 + q float64 + s float64 + oneminusQ float64 + oneminusQinv float64 + hxm float64 + hx0minusHxm float64 +} + +func (z *Zipf) h(x float64) float64 { + return math.Exp(z.oneminusQ*math.Log(z.v+x)) * z.oneminusQinv +} + +func (z *Zipf) hinv(x float64) float64 { + return math.Exp(z.oneminusQinv*math.Log(z.oneminusQ*x)) - z.v +} + +// NewZipf returns a Zipf variate generator. +// The generator generates values k ∈ [0, imax] +// such that P(k) is proportional to (v + k) ** (-s). +// Requirements: s > 1 and v >= 1. +func NewZipf(r *Rand, s float64, v float64, imax uint64) *Zipf { + z := new(Zipf) + if s <= 1.0 || v < 1 { + return nil + } + z.r = r + z.imax = float64(imax) + z.v = v + z.q = s + z.oneminusQ = 1.0 - z.q + z.oneminusQinv = 1.0 / z.oneminusQ + z.hxm = z.h(z.imax + 0.5) + z.hx0minusHxm = z.h(0.5) - math.Exp(math.Log(z.v)*(-z.q)) - z.hxm + z.s = 1 - z.hinv(z.h(1.5)-math.Exp(-z.q*math.Log(z.v+1.0))) + return z +} + +// Uint64 returns a value drawn from the Zipf distribution described +// by the Zipf object. +func (z *Zipf) Uint64() uint64 { + if z == nil { + panic("rand: nil Zipf") + } + k := 0.0 + + for { + r := z.r.Float64() // r on [0,1] + ur := z.hxm + r*z.hx0minusHxm + x := z.hinv(ur) + k = math.Floor(x + 0.5) + if k-x <= z.s { + break + } + if ur >= z.h(k+0.5)-math.Exp(-math.Log(k+z.v)*z.q) { + break + } + } + return uint64(k) +} diff --git a/contrib/go/_std_1.18/src/math/remainder.go b/contrib/go/_std_1.18/src/math/remainder.go new file mode 100644 index 0000000000..bf8bfd5553 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/remainder.go @@ -0,0 +1,94 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code and the comment below are from +// FreeBSD's /usr/src/lib/msun/src/e_remainder.c and came +// with this notice. The go code is a simplified version of +// the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_remainder(x,y) +// Return : +// returns x REM y = x - [x/y]*y as if in infinite +// precision arithmetic, where [x/y] is the (infinite bit) +// integer nearest x/y (in half way cases, choose the even one). +// Method : +// Based on Mod() returning x - [x/y]chopped * y exactly. + +// Remainder returns the IEEE 754 floating-point remainder of x/y. +// +// Special cases are: +// Remainder(±Inf, y) = NaN +// Remainder(NaN, y) = NaN +// Remainder(x, 0) = NaN +// Remainder(x, ±Inf) = x +// Remainder(x, NaN) = NaN +func Remainder(x, y float64) float64 { + if haveArchRemainder { + return archRemainder(x, y) + } + return remainder(x, y) +} + +func remainder(x, y float64) float64 { + const ( + Tiny = 4.45014771701440276618e-308 // 0x0020000000000000 + HalfMax = MaxFloat64 / 2 + ) + // special cases + switch { + case IsNaN(x) || IsNaN(y) || IsInf(x, 0) || y == 0: + return NaN() + case IsInf(y, 0): + return x + } + sign := false + if x < 0 { + x = -x + sign = true + } + if y < 0 { + y = -y + } + if x == y { + if sign { + zero := 0.0 + return -zero + } + return 0 + } + if y <= HalfMax { + x = Mod(x, y+y) // now x < 2y + } + if y < Tiny { + if x+x > y { + x -= y + if x+x >= y { + x -= y + } + } + } else { + yHalf := 0.5 * y + if x > yHalf { + x -= y + if x >= yHalf { + x -= y + } + } + } + if sign { + x = -x + } + return x +} diff --git a/contrib/go/_std_1.18/src/math/signbit.go b/contrib/go/_std_1.18/src/math/signbit.go new file mode 100644 index 0000000000..f6e61d660e --- /dev/null +++ b/contrib/go/_std_1.18/src/math/signbit.go @@ -0,0 +1,10 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Signbit reports whether x is negative or negative zero. +func Signbit(x float64) bool { + return Float64bits(x)&(1<<63) != 0 +} diff --git a/contrib/go/_std_1.18/src/math/sin.go b/contrib/go/_std_1.18/src/math/sin.go new file mode 100644 index 0000000000..d95bb548e8 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/sin.go @@ -0,0 +1,242 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point sine and cosine. +*/ + +// The original C code, the long comment, and the constants +// below were from http://netlib.sandia.gov/cephes/cmath/sin.c, +// available from http://www.netlib.org/cephes/cmath.tgz. +// The go code is a simplified version of the original C. +// +// sin.c +// +// Circular sine +// +// SYNOPSIS: +// +// double x, y, sin(); +// y = sin( x ); +// +// DESCRIPTION: +// +// Range reduction is into intervals of pi/4. The reduction error is nearly +// eliminated by contriving an extended precision modular arithmetic. +// +// Two polynomial approximating functions are employed. +// Between 0 and pi/4 the sine is approximated by +// x + x**3 P(x**2). +// Between pi/4 and pi/2 the cosine is represented as +// 1 - x**2 Q(x**2). +// +// ACCURACY: +// +// Relative error: +// arithmetic domain # trials peak rms +// DEC 0, 10 150000 3.0e-17 7.8e-18 +// IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 +// +// Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss +// is not gradual, but jumps suddenly to about 1 part in 10e7. Results may +// be meaningless for x > 2**49 = 5.6e14. +// +// cos.c +// +// Circular cosine +// +// SYNOPSIS: +// +// double x, y, cos(); +// y = cos( x ); +// +// DESCRIPTION: +// +// Range reduction is into intervals of pi/4. The reduction error is nearly +// eliminated by contriving an extended precision modular arithmetic. +// +// Two polynomial approximating functions are employed. +// Between 0 and pi/4 the cosine is approximated by +// 1 - x**2 Q(x**2). +// Between pi/4 and pi/2 the sine is represented as +// x + x**3 P(x**2). +// +// ACCURACY: +// +// Relative error: +// arithmetic domain # trials peak rms +// IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 +// DEC 0,+1.07e9 17000 3.0e-17 7.2e-18 +// +// Cephes Math Library Release 2.8: June, 2000 +// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier +// +// The readme file at http://netlib.sandia.gov/cephes/ says: +// Some software in this archive may be from the book _Methods and +// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +// International, 1989) or from the Cephes Mathematical Library, a +// commercial product. In either event, it is copyrighted by the author. +// What you see here may be used freely but it comes with no support or +// guarantee. +// +// The two known misprints in the book are repaired here in the +// source listings for the gamma function and the incomplete beta +// integral. +// +// Stephen L. Moshier +// moshier@na-net.ornl.gov + +// sin coefficients +var _sin = [...]float64{ + 1.58962301576546568060e-10, // 0x3de5d8fd1fd19ccd + -2.50507477628578072866e-8, // 0xbe5ae5e5a9291f5d + 2.75573136213857245213e-6, // 0x3ec71de3567d48a1 + -1.98412698295895385996e-4, // 0xbf2a01a019bfdf03 + 8.33333333332211858878e-3, // 0x3f8111111110f7d0 + -1.66666666666666307295e-1, // 0xbfc5555555555548 +} + +// cos coefficients +var _cos = [...]float64{ + -1.13585365213876817300e-11, // 0xbda8fa49a0861a9b + 2.08757008419747316778e-9, // 0x3e21ee9d7b4e3f05 + -2.75573141792967388112e-7, // 0xbe927e4f7eac4bc6 + 2.48015872888517045348e-5, // 0x3efa01a019c844f5 + -1.38888888888730564116e-3, // 0xbf56c16c16c14f91 + 4.16666666666665929218e-2, // 0x3fa555555555554b +} + +// Cos returns the cosine of the radian argument x. +// +// Special cases are: +// Cos(±Inf) = NaN +// Cos(NaN) = NaN +func Cos(x float64) float64 { + if haveArchCos { + return archCos(x) + } + return cos(x) +} + +func cos(x float64) float64 { + const ( + PI4A = 7.85398125648498535156e-1 // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B = 3.77489470793079817668e-8 // 0x3e64442d00000000, + PI4C = 2.69515142907905952645e-15 // 0x3ce8469898cc5170, + ) + // special cases + switch { + case IsNaN(x) || IsInf(x, 0): + return NaN() + } + + // make argument positive + sign := false + x = Abs(x) + + var j uint64 + var y, z float64 + if x >= reduceThreshold { + j, z = trigReduce(x) + } else { + j = uint64(x * (4 / Pi)) // integer part of x/(Pi/4), as integer for tests on the phase angle + y = float64(j) // integer part of x/(Pi/4), as float + + // map zeros to origin + if j&1 == 1 { + j++ + y++ + } + j &= 7 // octant modulo 2Pi radians (360 degrees) + z = ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic + } + + if j > 3 { + j -= 4 + sign = !sign + } + if j > 1 { + sign = !sign + } + + zz := z * z + if j == 1 || j == 2 { + y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5]) + } else { + y = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5]) + } + if sign { + y = -y + } + return y +} + +// Sin returns the sine of the radian argument x. +// +// Special cases are: +// Sin(±0) = ±0 +// Sin(±Inf) = NaN +// Sin(NaN) = NaN +func Sin(x float64) float64 { + if haveArchSin { + return archSin(x) + } + return sin(x) +} + +func sin(x float64) float64 { + const ( + PI4A = 7.85398125648498535156e-1 // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B = 3.77489470793079817668e-8 // 0x3e64442d00000000, + PI4C = 2.69515142907905952645e-15 // 0x3ce8469898cc5170, + ) + // special cases + switch { + case x == 0 || IsNaN(x): + return x // return ±0 || NaN() + case IsInf(x, 0): + return NaN() + } + + // make argument positive but save the sign + sign := false + if x < 0 { + x = -x + sign = true + } + + var j uint64 + var y, z float64 + if x >= reduceThreshold { + j, z = trigReduce(x) + } else { + j = uint64(x * (4 / Pi)) // integer part of x/(Pi/4), as integer for tests on the phase angle + y = float64(j) // integer part of x/(Pi/4), as float + + // map zeros to origin + if j&1 == 1 { + j++ + y++ + } + j &= 7 // octant modulo 2Pi radians (360 degrees) + z = ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic + } + // reflect in x axis + if j > 3 { + sign = !sign + j -= 4 + } + zz := z * z + if j == 1 || j == 2 { + y = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5]) + } else { + y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5]) + } + if sign { + y = -y + } + return y +} diff --git a/contrib/go/_std_1.18/src/math/sincos.go b/contrib/go/_std_1.18/src/math/sincos.go new file mode 100644 index 0000000000..5c5726f689 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/sincos.go @@ -0,0 +1,72 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// Coefficients _sin[] and _cos[] are found in pkg/math/sin.go. + +// Sincos returns Sin(x), Cos(x). +// +// Special cases are: +// Sincos(±0) = ±0, 1 +// Sincos(±Inf) = NaN, NaN +// Sincos(NaN) = NaN, NaN +func Sincos(x float64) (sin, cos float64) { + const ( + PI4A = 7.85398125648498535156e-1 // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B = 3.77489470793079817668e-8 // 0x3e64442d00000000, + PI4C = 2.69515142907905952645e-15 // 0x3ce8469898cc5170, + ) + // special cases + switch { + case x == 0: + return x, 1 // return ±0.0, 1.0 + case IsNaN(x) || IsInf(x, 0): + return NaN(), NaN() + } + + // make argument positive + sinSign, cosSign := false, false + if x < 0 { + x = -x + sinSign = true + } + + var j uint64 + var y, z float64 + if x >= reduceThreshold { + j, z = trigReduce(x) + } else { + j = uint64(x * (4 / Pi)) // integer part of x/(Pi/4), as integer for tests on the phase angle + y = float64(j) // integer part of x/(Pi/4), as float + + if j&1 == 1 { // map zeros to origin + j++ + y++ + } + j &= 7 // octant modulo 2Pi radians (360 degrees) + z = ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic + } + if j > 3 { // reflect in x axis + j -= 4 + sinSign, cosSign = !sinSign, !cosSign + } + if j > 1 { + cosSign = !cosSign + } + + zz := z * z + cos = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5]) + sin = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5]) + if j == 1 || j == 2 { + sin, cos = cos, sin + } + if cosSign { + cos = -cos + } + if sinSign { + sin = -sin + } + return +} diff --git a/contrib/go/_std_1.18/src/math/sinh.go b/contrib/go/_std_1.18/src/math/sinh.go new file mode 100644 index 0000000000..9fe9b4e17a --- /dev/null +++ b/contrib/go/_std_1.18/src/math/sinh.go @@ -0,0 +1,91 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point hyperbolic sine and cosine. + + The exponential func is called for arguments + greater in magnitude than 0.5. + + A series is used for arguments smaller in magnitude than 0.5. + + Cosh(x) is computed from the exponential func for + all arguments. +*/ + +// Sinh returns the hyperbolic sine of x. +// +// Special cases are: +// Sinh(±0) = ±0 +// Sinh(±Inf) = ±Inf +// Sinh(NaN) = NaN +func Sinh(x float64) float64 { + if haveArchSinh { + return archSinh(x) + } + return sinh(x) +} + +func sinh(x float64) float64 { + // The coefficients are #2029 from Hart & Cheney. (20.36D) + const ( + P0 = -0.6307673640497716991184787251e+6 + P1 = -0.8991272022039509355398013511e+5 + P2 = -0.2894211355989563807284660366e+4 + P3 = -0.2630563213397497062819489e+2 + Q0 = -0.6307673640497716991212077277e+6 + Q1 = 0.1521517378790019070696485176e+5 + Q2 = -0.173678953558233699533450911e+3 + ) + + sign := false + if x < 0 { + x = -x + sign = true + } + + var temp float64 + switch { + case x > 21: + temp = Exp(x) * 0.5 + + case x > 0.5: + ex := Exp(x) + temp = (ex - 1/ex) * 0.5 + + default: + sq := x * x + temp = (((P3*sq+P2)*sq+P1)*sq + P0) * x + temp = temp / (((sq+Q2)*sq+Q1)*sq + Q0) + } + + if sign { + temp = -temp + } + return temp +} + +// Cosh returns the hyperbolic cosine of x. +// +// Special cases are: +// Cosh(±0) = 1 +// Cosh(±Inf) = +Inf +// Cosh(NaN) = NaN +func Cosh(x float64) float64 { + if haveArchCosh { + return archCosh(x) + } + return cosh(x) +} + +func cosh(x float64) float64 { + x = Abs(x) + if x > 21 { + return Exp(x) * 0.5 + } + ex := Exp(x) + return (ex + 1/ex) * 0.5 +} diff --git a/contrib/go/_std_1.18/src/math/sqrt.go b/contrib/go/_std_1.18/src/math/sqrt.go new file mode 100644 index 0000000000..903d57d5e0 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/sqrt.go @@ -0,0 +1,149 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_sqrt(x) +// Return correctly rounded sqrt. +// ----------------------------------------- +// | Use the hardware sqrt if you have one | +// ----------------------------------------- +// Method: +// Bit by bit method using integer arithmetic. (Slow, but portable) +// 1. Normalization +// Scale x to y in [1,4) with even powers of 2: +// find an integer k such that 1 <= (y=x*2**(2k)) < 4, then +// sqrt(x) = 2**k * sqrt(y) +// 2. Bit by bit computation +// Let q = sqrt(y) truncated to i bit after binary point (q = 1), +// i 0 +// i+1 2 +// s = 2*q , and y = 2 * ( y - q ). (1) +// i i i i +// +// To compute q from q , one checks whether +// i+1 i +// +// -(i+1) 2 +// (q + 2 ) <= y. (2) +// i +// -(i+1) +// If (2) is false, then q = q ; otherwise q = q + 2 . +// i+1 i i+1 i +// +// With some algebraic manipulation, it is not difficult to see +// that (2) is equivalent to +// -(i+1) +// s + 2 <= y (3) +// i i +// +// The advantage of (3) is that s and y can be computed by +// i i +// the following recurrence formula: +// if (3) is false +// +// s = s , y = y ; (4) +// i+1 i i+1 i +// +// otherwise, +// -i -(i+1) +// s = s + 2 , y = y - s - 2 (5) +// i+1 i i+1 i i +// +// One may easily use induction to prove (4) and (5). +// Note. Since the left hand side of (3) contain only i+2 bits, +// it is not necessary to do a full (53-bit) comparison +// in (3). +// 3. Final rounding +// After generating the 53 bits result, we compute one more bit. +// Together with the remainder, we can decide whether the +// result is exact, bigger than 1/2ulp, or less than 1/2ulp +// (it will never equal to 1/2ulp). +// The rounding mode can be detected by checking whether +// huge + tiny is equal to huge, and whether huge - tiny is +// equal to huge for some floating point number "huge" and "tiny". +// +// +// Notes: Rounding mode detection omitted. The constants "mask", "shift", +// and "bias" are found in src/math/bits.go + +// Sqrt returns the square root of x. +// +// Special cases are: +// Sqrt(+Inf) = +Inf +// Sqrt(±0) = ±0 +// Sqrt(x < 0) = NaN +// Sqrt(NaN) = NaN +func Sqrt(x float64) float64 { + if haveArchSqrt { + return archSqrt(x) + } + return sqrt(x) +} + +// Note: Sqrt is implemented in assembly on some systems. +// Others have assembly stubs that jump to func sqrt below. +// On systems where Sqrt is a single instruction, the compiler +// may turn a direct call into a direct use of that instruction instead. + +func sqrt(x float64) float64 { + // special cases + switch { + case x == 0 || IsNaN(x) || IsInf(x, 1): + return x + case x < 0: + return NaN() + } + ix := Float64bits(x) + // normalize x + exp := int((ix >> shift) & mask) + if exp == 0 { // subnormal x + for ix&(1<<shift) == 0 { + ix <<= 1 + exp-- + } + exp++ + } + exp -= bias // unbias exponent + ix &^= mask << shift + ix |= 1 << shift + if exp&1 == 1 { // odd exp, double x to make it even + ix <<= 1 + } + exp >>= 1 // exp = exp/2, exponent of square root + // generate sqrt(x) bit by bit + ix <<= 1 + var q, s uint64 // q = sqrt(x) + r := uint64(1 << (shift + 1)) // r = moving bit from MSB to LSB + for r != 0 { + t := s + r + if t <= ix { + s = t + r + ix -= t + q += r + } + ix <<= 1 + r >>= 1 + } + // final rounding + if ix != 0 { // remainder, result not exact + q += q & 1 // round according to extra bit + } + ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent + return Float64frombits(ix) +} diff --git a/contrib/go/_std_1.18/src/math/sqrt_amd64.s b/contrib/go/_std_1.18/src/math/sqrt_amd64.s new file mode 100644 index 0000000000..c3b110e7c0 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/sqrt_amd64.s @@ -0,0 +1,12 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +// func archSqrt(x float64) float64 +TEXT ·archSqrt(SB), NOSPLIT, $0 + XORPS X0, X0 // break dependency + SQRTSD x+0(FP), X0 + MOVSD X0, ret+8(FP) + RET diff --git a/contrib/go/_std_1.18/src/math/sqrt_asm.go b/contrib/go/_std_1.18/src/math/sqrt_asm.go new file mode 100644 index 0000000000..2cec1a5903 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/sqrt_asm.go @@ -0,0 +1,11 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build 386 || amd64 || arm64 || arm || mips || mipsle || ppc64 || ppc64le || s390x || riscv64 || wasm + +package math + +const haveArchSqrt = true + +func archSqrt(x float64) float64 diff --git a/contrib/go/_std_1.18/src/math/stubs.go b/contrib/go/_std_1.18/src/math/stubs.go new file mode 100644 index 0000000000..c4350d4b87 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/stubs.go @@ -0,0 +1,160 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !s390x + +// This is a large group of functions that most architectures don't +// implement in assembly. + +package math + +const haveArchAcos = false + +func archAcos(x float64) float64 { + panic("not implemented") +} + +const haveArchAcosh = false + +func archAcosh(x float64) float64 { + panic("not implemented") +} + +const haveArchAsin = false + +func archAsin(x float64) float64 { + panic("not implemented") +} + +const haveArchAsinh = false + +func archAsinh(x float64) float64 { + panic("not implemented") +} + +const haveArchAtan = false + +func archAtan(x float64) float64 { + panic("not implemented") +} + +const haveArchAtan2 = false + +func archAtan2(y, x float64) float64 { + panic("not implemented") +} + +const haveArchAtanh = false + +func archAtanh(x float64) float64 { + panic("not implemented") +} + +const haveArchCbrt = false + +func archCbrt(x float64) float64 { + panic("not implemented") +} + +const haveArchCos = false + +func archCos(x float64) float64 { + panic("not implemented") +} + +const haveArchCosh = false + +func archCosh(x float64) float64 { + panic("not implemented") +} + +const haveArchErf = false + +func archErf(x float64) float64 { + panic("not implemented") +} + +const haveArchErfc = false + +func archErfc(x float64) float64 { + panic("not implemented") +} + +const haveArchExpm1 = false + +func archExpm1(x float64) float64 { + panic("not implemented") +} + +const haveArchFrexp = false + +func archFrexp(x float64) (float64, int) { + panic("not implemented") +} + +const haveArchLdexp = false + +func archLdexp(frac float64, exp int) float64 { + panic("not implemented") +} + +const haveArchLog10 = false + +func archLog10(x float64) float64 { + panic("not implemented") +} + +const haveArchLog2 = false + +func archLog2(x float64) float64 { + panic("not implemented") +} + +const haveArchLog1p = false + +func archLog1p(x float64) float64 { + panic("not implemented") +} + +const haveArchMod = false + +func archMod(x, y float64) float64 { + panic("not implemented") +} + +const haveArchPow = false + +func archPow(x, y float64) float64 { + panic("not implemented") +} + +const haveArchRemainder = false + +func archRemainder(x, y float64) float64 { + panic("not implemented") +} + +const haveArchSin = false + +func archSin(x float64) float64 { + panic("not implemented") +} + +const haveArchSinh = false + +func archSinh(x float64) float64 { + panic("not implemented") +} + +const haveArchTan = false + +func archTan(x float64) float64 { + panic("not implemented") +} + +const haveArchTanh = false + +func archTanh(x float64) float64 { + panic("not implemented") +} diff --git a/contrib/go/_std_1.18/src/math/tan.go b/contrib/go/_std_1.18/src/math/tan.go new file mode 100644 index 0000000000..a25417f527 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/tan.go @@ -0,0 +1,139 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +/* + Floating-point tangent. +*/ + +// The original C code, the long comment, and the constants +// below were from http://netlib.sandia.gov/cephes/cmath/sin.c, +// available from http://www.netlib.org/cephes/cmath.tgz. +// The go code is a simplified version of the original C. +// +// tan.c +// +// Circular tangent +// +// SYNOPSIS: +// +// double x, y, tan(); +// y = tan( x ); +// +// DESCRIPTION: +// +// Returns the circular tangent of the radian argument x. +// +// Range reduction is modulo pi/4. A rational function +// x + x**3 P(x**2)/Q(x**2) +// is employed in the basic interval [0, pi/4]. +// +// ACCURACY: +// Relative error: +// arithmetic domain # trials peak rms +// DEC +-1.07e9 44000 4.1e-17 1.0e-17 +// IEEE +-1.07e9 30000 2.9e-16 8.1e-17 +// +// Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss +// is not gradual, but jumps suddenly to about 1 part in 10e7. Results may +// be meaningless for x > 2**49 = 5.6e14. +// [Accuracy loss statement from sin.go comments.] +// +// Cephes Math Library Release 2.8: June, 2000 +// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier +// +// The readme file at http://netlib.sandia.gov/cephes/ says: +// Some software in this archive may be from the book _Methods and +// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +// International, 1989) or from the Cephes Mathematical Library, a +// commercial product. In either event, it is copyrighted by the author. +// What you see here may be used freely but it comes with no support or +// guarantee. +// +// The two known misprints in the book are repaired here in the +// source listings for the gamma function and the incomplete beta +// integral. +// +// Stephen L. Moshier +// moshier@na-net.ornl.gov + +// tan coefficients +var _tanP = [...]float64{ + -1.30936939181383777646e4, // 0xc0c992d8d24f3f38 + 1.15351664838587416140e6, // 0x413199eca5fc9ddd + -1.79565251976484877988e7, // 0xc1711fead3299176 +} +var _tanQ = [...]float64{ + 1.00000000000000000000e0, + 1.36812963470692954678e4, //0x40cab8a5eeb36572 + -1.32089234440210967447e6, //0xc13427bc582abc96 + 2.50083801823357915839e7, //0x4177d98fc2ead8ef + -5.38695755929454629881e7, //0xc189afe03cbe5a31 +} + +// Tan returns the tangent of the radian argument x. +// +// Special cases are: +// Tan(±0) = ±0 +// Tan(±Inf) = NaN +// Tan(NaN) = NaN +func Tan(x float64) float64 { + if haveArchTan { + return archTan(x) + } + return tan(x) +} + +func tan(x float64) float64 { + const ( + PI4A = 7.85398125648498535156e-1 // 0x3fe921fb40000000, Pi/4 split into three parts + PI4B = 3.77489470793079817668e-8 // 0x3e64442d00000000, + PI4C = 2.69515142907905952645e-15 // 0x3ce8469898cc5170, + ) + // special cases + switch { + case x == 0 || IsNaN(x): + return x // return ±0 || NaN() + case IsInf(x, 0): + return NaN() + } + + // make argument positive but save the sign + sign := false + if x < 0 { + x = -x + sign = true + } + var j uint64 + var y, z float64 + if x >= reduceThreshold { + j, z = trigReduce(x) + } else { + j = uint64(x * (4 / Pi)) // integer part of x/(Pi/4), as integer for tests on the phase angle + y = float64(j) // integer part of x/(Pi/4), as float + + /* map zeros and singularities to origin */ + if j&1 == 1 { + j++ + y++ + } + + z = ((x - y*PI4A) - y*PI4B) - y*PI4C + } + zz := z * z + + if zz > 1e-14 { + y = z + z*(zz*(((_tanP[0]*zz)+_tanP[1])*zz+_tanP[2])/((((zz+_tanQ[1])*zz+_tanQ[2])*zz+_tanQ[3])*zz+_tanQ[4])) + } else { + y = z + } + if j&2 == 2 { + y = -1 / y + } + if sign { + y = -y + } + return y +} diff --git a/contrib/go/_std_1.18/src/math/tanh.go b/contrib/go/_std_1.18/src/math/tanh.go new file mode 100644 index 0000000000..a825678424 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/tanh.go @@ -0,0 +1,104 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +// The original C code, the long comment, and the constants +// below were from http://netlib.sandia.gov/cephes/cmath/sin.c, +// available from http://www.netlib.org/cephes/cmath.tgz. +// The go code is a simplified version of the original C. +// tanh.c +// +// Hyperbolic tangent +// +// SYNOPSIS: +// +// double x, y, tanh(); +// +// y = tanh( x ); +// +// DESCRIPTION: +// +// Returns hyperbolic tangent of argument in the range MINLOG to MAXLOG. +// MAXLOG = 8.8029691931113054295988e+01 = log(2**127) +// MINLOG = -8.872283911167299960540e+01 = log(2**-128) +// +// A rational function is used for |x| < 0.625. The form +// x + x**3 P(x)/Q(x) of Cody & Waite is employed. +// Otherwise, +// tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). +// +// ACCURACY: +// +// Relative error: +// arithmetic domain # trials peak rms +// IEEE -2,2 30000 2.5e-16 5.8e-17 +// +// Cephes Math Library Release 2.8: June, 2000 +// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier +// +// The readme file at http://netlib.sandia.gov/cephes/ says: +// Some software in this archive may be from the book _Methods and +// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +// International, 1989) or from the Cephes Mathematical Library, a +// commercial product. In either event, it is copyrighted by the author. +// What you see here may be used freely but it comes with no support or +// guarantee. +// +// The two known misprints in the book are repaired here in the +// source listings for the gamma function and the incomplete beta +// integral. +// +// Stephen L. Moshier +// moshier@na-net.ornl.gov +// + +var tanhP = [...]float64{ + -9.64399179425052238628e-1, + -9.92877231001918586564e1, + -1.61468768441708447952e3, +} +var tanhQ = [...]float64{ + 1.12811678491632931402e2, + 2.23548839060100448583e3, + 4.84406305325125486048e3, +} + +// Tanh returns the hyperbolic tangent of x. +// +// Special cases are: +// Tanh(±0) = ±0 +// Tanh(±Inf) = ±1 +// Tanh(NaN) = NaN +func Tanh(x float64) float64 { + if haveArchTanh { + return archTanh(x) + } + return tanh(x) +} + +func tanh(x float64) float64 { + const MAXLOG = 8.8029691931113054295988e+01 // log(2**127) + z := Abs(x) + switch { + case z > 0.5*MAXLOG: + if x < 0 { + return -1 + } + return 1 + case z >= 0.625: + s := Exp(2 * z) + z = 1 - 2/(s+1) + if x < 0 { + z = -z + } + default: + if x == 0 { + return x + } + s := x * x + z = x + x*s*((tanhP[0]*s+tanhP[1])*s+tanhP[2])/(((s+tanhQ[0])*s+tanhQ[1])*s+tanhQ[2]) + } + return z +} diff --git a/contrib/go/_std_1.18/src/math/trig_reduce.go b/contrib/go/_std_1.18/src/math/trig_reduce.go new file mode 100644 index 0000000000..5cdf4fa013 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/trig_reduce.go @@ -0,0 +1,100 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +import ( + "math/bits" +) + +// reduceThreshold is the maximum value of x where the reduction using Pi/4 +// in 3 float64 parts still gives accurate results. This threshold +// is set by y*C being representable as a float64 without error +// where y is given by y = floor(x * (4 / Pi)) and C is the leading partial +// terms of 4/Pi. Since the leading terms (PI4A and PI4B in sin.go) have 30 +// and 32 trailing zero bits, y should have less than 30 significant bits. +// y < 1<<30 -> floor(x*4/Pi) < 1<<30 -> x < (1<<30 - 1) * Pi/4 +// So, conservatively we can take x < 1<<29. +// Above this threshold Payne-Hanek range reduction must be used. +const reduceThreshold = 1 << 29 + +// trigReduce implements Payne-Hanek range reduction by Pi/4 +// for x > 0. It returns the integer part mod 8 (j) and +// the fractional part (z) of x / (Pi/4). +// The implementation is based on: +// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit" +// K. C. Ng et al, March 24, 1992 +// The simulated multi-precision calculation of x*B uses 64-bit integer arithmetic. +func trigReduce(x float64) (j uint64, z float64) { + const PI4 = Pi / 4 + if x < PI4 { + return 0, x + } + // Extract out the integer and exponent such that, + // x = ix * 2 ** exp. + ix := Float64bits(x) + exp := int(ix>>shift&mask) - bias - shift + ix &^= mask << shift + ix |= 1 << shift + // Use the exponent to extract the 3 appropriate uint64 digits from mPi4, + // B ~ (z0, z1, z2), such that the product leading digit has the exponent -61. + // Note, exp >= -53 since x >= PI4 and exp < 971 for maximum float64. + digit, bitshift := uint(exp+61)/64, uint(exp+61)%64 + z0 := (mPi4[digit] << bitshift) | (mPi4[digit+1] >> (64 - bitshift)) + z1 := (mPi4[digit+1] << bitshift) | (mPi4[digit+2] >> (64 - bitshift)) + z2 := (mPi4[digit+2] << bitshift) | (mPi4[digit+3] >> (64 - bitshift)) + // Multiply mantissa by the digits and extract the upper two digits (hi, lo). + z2hi, _ := bits.Mul64(z2, ix) + z1hi, z1lo := bits.Mul64(z1, ix) + z0lo := z0 * ix + lo, c := bits.Add64(z1lo, z2hi, 0) + hi, _ := bits.Add64(z0lo, z1hi, c) + // The top 3 bits are j. + j = hi >> 61 + // Extract the fraction and find its magnitude. + hi = hi<<3 | lo>>61 + lz := uint(bits.LeadingZeros64(hi)) + e := uint64(bias - (lz + 1)) + // Clear implicit mantissa bit and shift into place. + hi = (hi << (lz + 1)) | (lo >> (64 - (lz + 1))) + hi >>= 64 - shift + // Include the exponent and convert to a float. + hi |= e << shift + z = Float64frombits(hi) + // Map zeros to origin. + if j&1 == 1 { + j++ + j &= 7 + z-- + } + // Multiply the fractional part by pi/4. + return j, z * PI4 +} + +// mPi4 is the binary digits of 4/pi as a uint64 array, +// that is, 4/pi = Sum mPi4[i]*2^(-64*i) +// 19 64-bit digits and the leading one bit give 1217 bits +// of precision to handle the largest possible float64 exponent. +var mPi4 = [...]uint64{ + 0x0000000000000001, + 0x45f306dc9c882a53, + 0xf84eafa3ea69bb81, + 0xb6c52b3278872083, + 0xfca2c757bd778ac3, + 0x6e48dc74849ba5c0, + 0x0c925dd413a32439, + 0xfc3bd63962534e7d, + 0xd1046bea5d768909, + 0xd338e04d68befc82, + 0x7323ac7306a673e9, + 0x3908bf177bf25076, + 0x3ff12fffbc0b301f, + 0xde5e2316b414da3e, + 0xda6cfd9e4f96136e, + 0x9e8c7ecd3cbfd45a, + 0xea4f758fd7cbe2f6, + 0x7a0e73ef14a525d4, + 0xd7f6bf623f1aba10, + 0xac06608df8f6d757, +} diff --git a/contrib/go/_std_1.18/src/math/unsafe.go b/contrib/go/_std_1.18/src/math/unsafe.go new file mode 100644 index 0000000000..e59f50ca62 --- /dev/null +++ b/contrib/go/_std_1.18/src/math/unsafe.go @@ -0,0 +1,29 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +import "unsafe" + +// Float32bits returns the IEEE 754 binary representation of f, +// with the sign bit of f and the result in the same bit position. +// Float32bits(Float32frombits(x)) == x. +func Float32bits(f float32) uint32 { return *(*uint32)(unsafe.Pointer(&f)) } + +// Float32frombits returns the floating-point number corresponding +// to the IEEE 754 binary representation b, with the sign bit of b +// and the result in the same bit position. +// Float32frombits(Float32bits(x)) == x. +func Float32frombits(b uint32) float32 { return *(*float32)(unsafe.Pointer(&b)) } + +// Float64bits returns the IEEE 754 binary representation of f, +// with the sign bit of f and the result in the same bit position, +// and Float64bits(Float64frombits(x)) == x. +func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) } + +// Float64frombits returns the floating-point number corresponding +// to the IEEE 754 binary representation b, with the sign bit of b +// and the result in the same bit position. +// Float64frombits(Float64bits(x)) == x. +func Float64frombits(b uint64) float64 { return *(*float64)(unsafe.Pointer(&b)) } |