github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/compiler/natives/src/math/math.go (about)

     1  //go:build js
     2  // +build js
     3  
     4  package math
     5  
     6  import (
     7  	"github.com/gopherjs/gopherjs/js"
     8  )
     9  
    10  var (
    11  	math           = js.Global.Get("Math")
    12  	_zero  float64 = 0
    13  	posInf         = 1 / _zero
    14  	negInf         = -1 / _zero
    15  )
    16  
    17  // Usually, NaN can be obtained in JavaScript with `0 / 0` operation. However,
    18  // in V8, `0 / _zero` yields a bitwise-different value of NaN compared to the
    19  // default NaN or `0 / 0`. Unfortunately, Go compiler forbids division by zero,
    20  // so we have to get this value from prelude.
    21  var nan = js.Global.Get("$NaN").Float()
    22  
    23  func Acos(x float64) float64 {
    24  	return math.Call("acos", x).Float()
    25  }
    26  
    27  func Acosh(x float64) float64 {
    28  	return math.Call("acosh", x).Float()
    29  }
    30  
    31  func Asin(x float64) float64 {
    32  	return math.Call("asin", x).Float()
    33  }
    34  
    35  func Asinh(x float64) float64 {
    36  	return math.Call("asinh", x).Float()
    37  }
    38  
    39  func Atan(x float64) float64 {
    40  	return math.Call("atan", x).Float()
    41  }
    42  
    43  func Atanh(x float64) float64 {
    44  	return math.Call("atanh", x).Float()
    45  }
    46  
    47  func Atan2(y, x float64) float64 {
    48  	return math.Call("atan2", y, x).Float()
    49  }
    50  
    51  func Cbrt(x float64) float64 {
    52  	return math.Call("cbrt", x).Float()
    53  }
    54  
    55  func Ceil(x float64) float64 {
    56  	return math.Call("ceil", x).Float()
    57  }
    58  
    59  func Copysign(x, y float64) float64 {
    60  	if (x < 0 || 1/x == negInf) != (y < 0 || 1/y == negInf) {
    61  		return -x
    62  	}
    63  	return x
    64  }
    65  
    66  func Cos(x float64) float64 {
    67  	return math.Call("cos", x).Float()
    68  }
    69  
    70  func Cosh(x float64) float64 {
    71  	return math.Call("cosh", x).Float()
    72  }
    73  
    74  func Erf(x float64) float64 {
    75  	return erf(x)
    76  }
    77  
    78  func Erfc(x float64) float64 {
    79  	return erfc(x)
    80  }
    81  
    82  func Exp(x float64) float64 {
    83  	return math.Call("exp", x).Float()
    84  }
    85  
    86  func Exp2(x float64) float64 {
    87  	return math.Call("pow", 2, x).Float()
    88  }
    89  
    90  func Expm1(x float64) float64 {
    91  	return expm1(x)
    92  }
    93  
    94  func Floor(x float64) float64 {
    95  	return math.Call("floor", x).Float()
    96  }
    97  
    98  func Frexp(f float64) (frac float64, exp int) {
    99  	return frexp(f)
   100  }
   101  
   102  func Hypot(p, q float64) float64 {
   103  	return hypot(p, q)
   104  }
   105  
   106  func Inf(sign int) float64 {
   107  	switch {
   108  	case sign >= 0:
   109  		return posInf
   110  	default:
   111  		return negInf
   112  	}
   113  }
   114  
   115  func IsInf(f float64, sign int) bool {
   116  	if f == posInf {
   117  		return sign >= 0
   118  	}
   119  	if f == negInf {
   120  		return sign <= 0
   121  	}
   122  	return false
   123  }
   124  
   125  func IsNaN(f float64) (is bool) {
   126  	return f != f
   127  }
   128  
   129  func Ldexp(frac float64, exp int) float64 {
   130  	if -1024 < exp && exp < 1024 { // Use Math.pow for small exp values where it's viable. For performance.
   131  		if frac == 0 {
   132  			return frac
   133  		}
   134  		return frac * math.Call("pow", 2, exp).Float()
   135  	}
   136  	return ldexp(frac, exp)
   137  }
   138  
   139  func Log(x float64) float64 {
   140  	if x != x { // workaround for optimizer bug in V8, remove at some point
   141  		return nan
   142  	}
   143  	return math.Call("log", x).Float()
   144  }
   145  
   146  func Log10(x float64) float64 {
   147  	return log10(x)
   148  }
   149  
   150  func Log1p(x float64) float64 {
   151  	return log1p(x)
   152  }
   153  
   154  func Log2(x float64) float64 {
   155  	return log2(x)
   156  }
   157  
   158  func Max(x, y float64) float64 {
   159  	return max(x, y)
   160  }
   161  
   162  func Min(x, y float64) float64 {
   163  	return min(x, y)
   164  }
   165  
   166  func Mod(x, y float64) float64 {
   167  	return js.Global.Call("$mod", x, y).Float()
   168  }
   169  
   170  func Modf(f float64) (float64, float64) {
   171  	if f == posInf || f == negInf {
   172  		return f, nan
   173  	}
   174  	if 1/f == negInf {
   175  		return f, f
   176  	}
   177  	frac := Mod(f, 1)
   178  	return f - frac, frac
   179  }
   180  
   181  func NaN() float64 {
   182  	return nan
   183  }
   184  
   185  func Pow(x, y float64) float64 {
   186  	if x == 1 || (x == -1 && (y == posInf || y == negInf)) {
   187  		return 1
   188  	}
   189  	return math.Call("pow", x, y).Float()
   190  }
   191  
   192  func Remainder(x, y float64) float64 {
   193  	return remainder(x, y)
   194  }
   195  
   196  func Signbit(x float64) bool {
   197  	return x < 0 || 1/x == negInf
   198  }
   199  
   200  func Sin(x float64) float64 {
   201  	return math.Call("sin", x).Float()
   202  }
   203  
   204  func Sinh(x float64) float64 {
   205  	return math.Call("sinh", x).Float()
   206  }
   207  
   208  func Sincos(x float64) (sin, cos float64) {
   209  	return Sin(x), Cos(x)
   210  }
   211  
   212  func Sqrt(x float64) float64 {
   213  	return math.Call("sqrt", x).Float()
   214  }
   215  
   216  func Tan(x float64) float64 {
   217  	return math.Call("tan", x).Float()
   218  }
   219  
   220  func Tanh(x float64) float64 {
   221  	return math.Call("tanh", x).Float()
   222  }
   223  
   224  func Trunc(x float64) float64 {
   225  	if x == posInf || x == negInf || x != x || 1/x == negInf {
   226  		return x
   227  	}
   228  	return Copysign(float64(int(x)), x)
   229  }
   230  
   231  var buf struct {
   232  	uint32array  [2]uint32
   233  	float32array [2]float32
   234  	float64array [1]float64
   235  }
   236  
   237  func init() {
   238  	ab := js.Global.Get("ArrayBuffer").New(8)
   239  	js.InternalObject(buf).Set("uint32array", js.Global.Get("Uint32Array").New(ab))
   240  	js.InternalObject(buf).Set("float32array", js.Global.Get("Float32Array").New(ab))
   241  	js.InternalObject(buf).Set("float64array", js.Global.Get("Float64Array").New(ab))
   242  }
   243  
   244  func Float32bits(f float32) uint32 {
   245  	buf.float32array[0] = f
   246  	return buf.uint32array[0]
   247  }
   248  
   249  func Float32frombits(b uint32) float32 {
   250  	buf.uint32array[0] = b
   251  	return buf.float32array[0]
   252  }
   253  
   254  func Float64bits(f float64) uint64 {
   255  	buf.float64array[0] = f
   256  	return uint64(buf.uint32array[1])<<32 + uint64(buf.uint32array[0])
   257  }
   258  
   259  func Float64frombits(b uint64) float64 {
   260  	buf.uint32array[0] = uint32(b)
   261  	buf.uint32array[1] = uint32(b >> 32)
   262  	return buf.float64array[0]
   263  }