1// Copyright 2018 The CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Copyright 2018 The Go Authors. All rights reserved.
16// Use of this source code is governed by a BSD-style
17// license that can be found in the LICENSE file.
18
19package math
20
21import (
22 "math"
23
24 "github.com/cockroachdb/apd/v3"
25
26 "cuelang.org/go/internal"
27)
28
29// Abs returns the absolute value of x.
30//
31// Special case: Abs(±Inf) = +Inf
32func Abs(x *internal.Decimal) (*internal.Decimal, error) {
33 var d internal.Decimal
34 _, err := internal.BaseContext.Abs(&d, x)
35 return &d, err
36}
37
38// Acosh returns the inverse hyperbolic cosine of x.
39//
40// Special cases are:
41//
42// Acosh(+Inf) = +Inf
43// Acosh(x) = NaN if x < 1
44// Acosh(NaN) = NaN
45func Acosh(x float64) float64 {
46 return math.Acosh(x)
47}
48
49// Asin returns the arcsine, in radians, of x.
50//
51// Special cases are:
52//
53// Asin(±0) = ±0
54// Asin(x) = NaN if x < -1 or x > 1
55func Asin(x float64) float64 {
56 return math.Asin(x)
57}
58
59// Acos returns the arccosine, in radians, of x.
60//
61// Special case is:
62//
63// Acos(x) = NaN if x < -1 or x > 1
64func Acos(x float64) float64 {
65 return math.Acos(x)
66}
67
68// Asinh returns the inverse hyperbolic sine of x.
69//
70// Special cases are:
71//
72// Asinh(±0) = ±0
73// Asinh(±Inf) = ±Inf
74// Asinh(NaN) = NaN
75func Asinh(x float64) float64 {
76 return math.Asinh(x)
77}
78
79// Atan returns the arctangent, in radians, of x.
80//
81// Special cases are:
82//
83// Atan(±0) = ±0
84// Atan(±Inf) = ±Pi/2
85func Atan(x float64) float64 {
86 return math.Atan(x)
87}
88
89// Atan2 returns the arc tangent of y/x, using
90// the signs of the two to determine the quadrant
91// of the return value.
92//
93// Special cases are (in order):
94//
95// Atan2(y, NaN) = NaN
96// Atan2(NaN, x) = NaN
97// Atan2(+0, x>=0) = +0
98// Atan2(-0, x>=0) = -0
99// Atan2(+0, x<=-0) = +Pi
100// Atan2(-0, x<=-0) = -Pi
101// Atan2(y>0, 0) = +Pi/2
102// Atan2(y<0, 0) = -Pi/2
103// Atan2(+Inf, +Inf) = +Pi/4
104// Atan2(-Inf, +Inf) = -Pi/4
105// Atan2(+Inf, -Inf) = 3Pi/4
106// Atan2(-Inf, -Inf) = -3Pi/4
107// Atan2(y, +Inf) = 0
108// Atan2(y>0, -Inf) = +Pi
109// Atan2(y<0, -Inf) = -Pi
110// Atan2(+Inf, x) = +Pi/2
111// Atan2(-Inf, x) = -Pi/2
112func Atan2(y, x float64) float64 {
113 return math.Atan2(y, x)
114}
115
116// Atanh returns the inverse hyperbolic tangent of x.
117//
118// Special cases are:
119//
120// Atanh(1) = +Inf
121// Atanh(±0) = ±0
122// Atanh(-1) = -Inf
123// Atanh(x) = NaN if x < -1 or x > 1
124// Atanh(NaN) = NaN
125func Atanh(x float64) float64 {
126 return math.Atanh(x)
127}
128
129// Cbrt returns the cube root of x.
130//
131// Special cases are:
132//
133// Cbrt(±0) = ±0
134// Cbrt(±Inf) = ±Inf
135// Cbrt(NaN) = NaN
136func Cbrt(x *internal.Decimal) (*internal.Decimal, error) {
137 var d internal.Decimal
138 _, err := internal.BaseContext.Cbrt(&d, x)
139 return &d, err
140}
141
142// Mathematical constants.
143const (
144 E = 2.71828182845904523536028747135266249775724709369995957496696763 // https://oeis.org/A001113
145 Pi = 3.14159265358979323846264338327950288419716939937510582097494459 // https://oeis.org/A000796
146 Phi = 1.61803398874989484820458683436563811772030917980576286213544862 // https://oeis.org/A001622
147
148 Sqrt2 = 1.41421356237309504880168872420969807856967187537694807317667974 // https://oeis.org/A002193
149 SqrtE = 1.64872127070012814684865078781416357165377610071014801157507931 // https://oeis.org/A019774
150 SqrtPi = 1.77245385090551602729816748334114518279754945612238712821380779 // https://oeis.org/A002161
151 SqrtPhi = 1.27201964951406896425242246173749149171560804184009624861664038 // https://oeis.org/A139339
152
153 Ln2 = 0.693147180559945309417232121458176568075500134360255254120680009 // https://oeis.org/A002162
154 Log2E = 1 / Ln2
155 Ln10 = 2.30258509299404568401799145468436420760110148862877297603332790 // https://oeis.org/A002392
156 Log10E = 1 / Ln10
157)
158
159// Copysign returns a value with the magnitude
160// of x and the sign of y.
161func Copysign(x, y *internal.Decimal) *internal.Decimal {
162 var d internal.Decimal
163 d.Set(x)
164 d.Negative = y.Negative
165 return &d
166}
167
168var zero = apd.New(0, 0)
169
170// Dim returns the maximum of x-y or 0.
171//
172// Special cases are:
173//
174// Dim(+Inf, +Inf) = NaN
175// Dim(-Inf, -Inf) = NaN
176// Dim(x, NaN) = Dim(NaN, x) = NaN
177func Dim(x, y *internal.Decimal) (*internal.Decimal, error) {
178 var d internal.Decimal
179 _, err := internal.BaseContext.Sub(&d, x, y)
180 if err != nil {
181 return nil, err
182 }
183 if d.Negative {
184 return zero, nil
185 }
186 return &d, nil
187}
188
189// Erf returns the error function of x.
190//
191// Special cases are:
192//
193// Erf(+Inf) = 1
194// Erf(-Inf) = -1
195// Erf(NaN) = NaN
196func Erf(x float64) float64 {
197 return math.Erf(x)
198}
199
200// Erfc returns the complementary error function of x.
201//
202// Special cases are:
203//
204// Erfc(+Inf) = 0
205// Erfc(-Inf) = 2
206// Erfc(NaN) = NaN
207func Erfc(x float64) float64 {
208 return math.Erfc(x)
209}
210
211// Erfinv returns the inverse error function of x.
212//
213// Special cases are:
214//
215// Erfinv(1) = +Inf
216// Erfinv(-1) = -Inf
217// Erfinv(x) = NaN if x < -1 or x > 1
218// Erfinv(NaN) = NaN
219func Erfinv(x float64) float64 {
220 return math.Erfinv(x)
221}
222
223// Erfcinv returns the inverse of Erfc(x).
224//
225// Special cases are:
226//
227// Erfcinv(0) = +Inf
228// Erfcinv(2) = -Inf
229// Erfcinv(x) = NaN if x < 0 or x > 2
230// Erfcinv(NaN) = NaN
231func Erfcinv(x float64) float64 {
232 return math.Erfcinv(x)
233}
234
235// Exp returns e**x, the base-e exponential of x.
236//
237// Special cases are:
238//
239// Exp(+Inf) = +Inf
240// Exp(NaN) = NaN
241//
242// Very large values overflow to 0 or +Inf.
243// Very small values underflow to 1.
244func Exp(x *internal.Decimal) (*internal.Decimal, error) {
245 var d internal.Decimal
246 _, err := internal.BaseContext.Exp(&d, x)
247 return &d, err
248}
249
250var two = apd.New(2, 0)
251
252// Exp2 returns 2**x, the base-2 exponential of x.
253//
254// Special cases are the same as Exp.
255func Exp2(x *internal.Decimal) (*internal.Decimal, error) {
256 var d internal.Decimal
257 _, err := internal.BaseContext.Pow(&d, two, x)
258 return &d, err
259}
260
261// Expm1 returns e**x - 1, the base-e exponential of x minus 1.
262// It is more accurate than Exp(x) - 1 when x is near zero.
263//
264// Special cases are:
265//
266// Expm1(+Inf) = +Inf
267// Expm1(-Inf) = -1
268// Expm1(NaN) = NaN
269//
270// Very large values overflow to -1 or +Inf.
271func Expm1(x float64) float64 {
272 return math.Expm1(x)
273}
274
275// Gamma returns the Gamma function of x.
276//
277// Special cases are:
278//
279// Gamma(+Inf) = +Inf
280// Gamma(+0) = +Inf
281// Gamma(-0) = -Inf
282// Gamma(x) = NaN for integer x < 0
283// Gamma(-Inf) = NaN
284// Gamma(NaN) = NaN
285func Gamma(x float64) float64 {
286 return math.Gamma(x)
287}
288
289// Hypot returns Sqrt(p*p + q*q), taking care to avoid
290// unnecessary overflow and underflow.
291//
292// Special cases are:
293//
294// Hypot(±Inf, q) = +Inf
295// Hypot(p, ±Inf) = +Inf
296// Hypot(NaN, q) = NaN
297// Hypot(p, NaN) = NaN
298func Hypot(p, q float64) float64 {
299 return math.Hypot(p, q)
300}
301
302// J0 returns the order-zero Bessel function of the first kind.
303//
304// Special cases are:
305//
306// J0(±Inf) = 0
307// J0(0) = 1
308// J0(NaN) = NaN
309func J0(x float64) float64 {
310 return math.J0(x)
311}
312
313// Y0 returns the order-zero Bessel function of the second kind.
314//
315// Special cases are:
316//
317// Y0(+Inf) = 0
318// Y0(0) = -Inf
319// Y0(x < 0) = NaN
320// Y0(NaN) = NaN
321func Y0(x float64) float64 {
322 return math.Y0(x)
323}
324
325// J1 returns the order-one Bessel function of the first kind.
326//
327// Special cases are:
328//
329// J1(±Inf) = 0
330// J1(NaN) = NaN
331func J1(x float64) float64 {
332 return math.J1(x)
333}
334
335// Y1 returns the order-one Bessel function of the second kind.
336//
337// Special cases are:
338//
339// Y1(+Inf) = 0
340// Y1(0) = -Inf
341// Y1(x < 0) = NaN
342// Y1(NaN) = NaN
343func Y1(x float64) float64 {
344 return math.Y1(x)
345}
346
347// Jn returns the order-n Bessel function of the first kind.
348//
349// Special cases are:
350//
351// Jn(n, ±Inf) = 0
352// Jn(n, NaN) = NaN
353func Jn(n int, x float64) float64 {
354 return math.Jn(n, x)
355}
356
357// Yn returns the order-n Bessel function of the second kind.
358//
359// Special cases are:
360//
361// Yn(n, +Inf) = 0
362// Yn(n ≥ 0, 0) = -Inf
363// Yn(n < 0, 0) = +Inf if n is odd, -Inf if n is even
364// Yn(n, x < 0) = NaN
365// Yn(n, NaN) = NaN
366func Yn(n int, x float64) float64 {
367 return math.Yn(n, x)
368}
369
370// Ldexp is the inverse of Frexp.
371// It returns frac × 2**exp.
372//
373// Special cases are:
374//
375// Ldexp(±0, exp) = ±0
376// Ldexp(±Inf, exp) = ±Inf
377// Ldexp(NaN, exp) = NaN
378func Ldexp(frac float64, exp int) float64 {
379 return math.Ldexp(frac, exp)
380}
381
382// Log returns the natural logarithm of x.
383//
384// Special cases are:
385//
386// Log(+Inf) = +Inf
387// Log(0) = -Inf
388// Log(x < 0) = NaN
389// Log(NaN) = NaN
390func Log(x *internal.Decimal) (*internal.Decimal, error) {
391 var d internal.Decimal
392 _, err := internal.BaseContext.Ln(&d, x)
393 return &d, err
394}
395
396// Log10 returns the decimal logarithm of x.
397// The special cases are the same as for Log.
398func Log10(x *internal.Decimal) (*internal.Decimal, error) {
399 var d internal.Decimal
400 _, err := internal.BaseContext.Log10(&d, x)
401 return &d, err
402}
403
404// Log2 returns the binary logarithm of x.
405// The special cases are the same as for Log.
406func Log2(x *internal.Decimal) (*internal.Decimal, error) {
407 var d, ln2 internal.Decimal
408 _, _ = internal.BaseContext.Ln(&ln2, two)
409 _, err := internal.BaseContext.Ln(&d, x)
410 if err != nil {
411 return &d, err
412 }
413 _, err = internal.BaseContext.Quo(&d, &d, &ln2)
414 return &d, err
415}
416
417// Log1p returns the natural logarithm of 1 plus its argument x.
418// It is more accurate than Log(1 + x) when x is near zero.
419//
420// Special cases are:
421//
422// Log1p(+Inf) = +Inf
423// Log1p(±0) = ±0
424// Log1p(-1) = -Inf
425// Log1p(x < -1) = NaN
426// Log1p(NaN) = NaN
427func Log1p(x float64) float64 {
428 return math.Log1p(x)
429}
430
431// Logb returns the binary exponent of x.
432//
433// Special cases are:
434//
435// Logb(±Inf) = +Inf
436// Logb(0) = -Inf
437// Logb(NaN) = NaN
438func Logb(x float64) float64 {
439 return math.Logb(x)
440}
441
442// Ilogb returns the binary exponent of x as an integer.
443//
444// Special cases are:
445//
446// Ilogb(±Inf) = MaxInt32
447// Ilogb(0) = MinInt32
448// Ilogb(NaN) = MaxInt32
449func Ilogb(x float64) int {
450 return math.Ilogb(x)
451}
452
453// Mod returns the floating-point remainder of x/y.
454// The magnitude of the result is less than y and its
455// sign agrees with that of x.
456//
457// Special cases are:
458//
459// Mod(±Inf, y) = NaN
460// Mod(NaN, y) = NaN
461// Mod(x, 0) = NaN
462// Mod(x, ±Inf) = x
463// Mod(x, NaN) = NaN
464func Mod(x, y float64) float64 {
465 return math.Mod(x, y)
466}
467
468// Pow returns x**y, the base-x exponential of y.
469//
470// Special cases are (in order):
471//
472// Pow(x, ±0) = 1 for any x
473// Pow(1, y) = 1 for any y
474// Pow(x, 1) = x for any x
475// Pow(NaN, y) = NaN
476// Pow(x, NaN) = NaN
477// Pow(±0, y) = ±Inf for y an odd integer < 0
478// Pow(±0, -Inf) = +Inf
479// Pow(±0, +Inf) = +0
480// Pow(±0, y) = +Inf for finite y < 0 and not an odd integer
481// Pow(±0, y) = ±0 for y an odd integer > 0
482// Pow(±0, y) = +0 for finite y > 0 and not an odd integer
483// Pow(-1, ±Inf) = 1
484// Pow(x, +Inf) = +Inf for |x| > 1
485// Pow(x, -Inf) = +0 for |x| > 1
486// Pow(x, +Inf) = +0 for |x| < 1
487// Pow(x, -Inf) = +Inf for |x| < 1
488// Pow(+Inf, y) = +Inf for y > 0
489// Pow(+Inf, y) = +0 for y < 0
490// Pow(-Inf, y) = Pow(-0, -y)
491// Pow(x, y) = NaN for finite x < 0 and finite non-integer y
492func Pow(x, y *internal.Decimal) (*internal.Decimal, error) {
493 var d internal.Decimal
494 _, err := internal.BaseContext.Pow(&d, x, y)
495 return &d, err
496}
497
498// Pow10 returns 10**n, the base-10 exponential of n.
499func Pow10(n int32) *internal.Decimal {
500 return apd.New(1, n)
501}
502
503// Remainder returns the IEEE 754 floating-point remainder of x/y.
504//
505// Special cases are:
506//
507// Remainder(±Inf, y) = NaN
508// Remainder(NaN, y) = NaN
509// Remainder(x, 0) = NaN
510// Remainder(x, ±Inf) = x
511// Remainder(x, NaN) = NaN
512func Remainder(x, y float64) float64 {
513 return math.Remainder(x, y)
514}
515
516// Signbit reports whether x is negative or negative zero.
517func Signbit(x *internal.Decimal) bool {
518 return x.Negative
519}
520
521// Cos returns the cosine of the radian argument x.
522//
523// Special cases are:
524//
525// Cos(±Inf) = NaN
526// Cos(NaN) = NaN
527func Cos(x float64) float64 {
528 return math.Cos(x)
529}
530
531// Sin returns the sine of the radian argument x.
532//
533// Special cases are:
534//
535// Sin(±0) = ±0
536// Sin(±Inf) = NaN
537// Sin(NaN) = NaN
538func Sin(x float64) float64 {
539 return math.Sin(x)
540}
541
542// Sinh returns the hyperbolic sine of x.
543//
544// Special cases are:
545//
546// Sinh(±0) = ±0
547// Sinh(±Inf) = ±Inf
548// Sinh(NaN) = NaN
549func Sinh(x float64) float64 {
550 return math.Sinh(x)
551}
552
553// Cosh returns the hyperbolic cosine of x.
554//
555// Special cases are:
556//
557// Cosh(±0) = 1
558// Cosh(±Inf) = +Inf
559// Cosh(NaN) = NaN
560func Cosh(x float64) float64 {
561 return math.Cosh(x)
562}
563
564// Sqrt returns the square root of x.
565//
566// Special cases are:
567//
568// Sqrt(+Inf) = +Inf
569// Sqrt(±0) = ±0
570// Sqrt(x < 0) = NaN
571// Sqrt(NaN) = NaN
572func Sqrt(x float64) float64 {
573 return math.Sqrt(x)
574}
575
576// Tan returns the tangent of the radian argument x.
577//
578// Special cases are:
579//
580// Tan(±0) = ±0
581// Tan(±Inf) = NaN
582// Tan(NaN) = NaN
583func Tan(x float64) float64 {
584 return math.Tan(x)
585}
586
587// Tanh returns the hyperbolic tangent of x.
588//
589// Special cases are:
590//
591// Tanh(±0) = ±0
592// Tanh(±Inf) = ±1
593// Tanh(NaN) = NaN
594func Tanh(x float64) float64 {
595 return math.Tanh(x)
596}