-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmath.tau
More file actions
90 lines (77 loc) · 3.06 KB
/
Copy pathmath.tau
File metadata and controls
90 lines (77 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# math - the usual functions on floats.
#
# Everything returns a float, whatever it was given: an integer handed to one
# of these is converted on the way into C and comes back a float, and stays
# one through the arithmetic that follows.
#
# The functions are the ones of the C math library, declared and called
# through the ffi module. There is no shared object of our own in between,
# since the interpreter is already linked against libm and dlopen(null) is the
# handle of the program itself.
ffi = import("ffi")
# The C library the program was linked against.
libm = dlopen(null)
Pi = 3.141592653589793
E = 2.718281828459045
Sqrt2 = 1.4142135623730951
SqrtPi = 1.772453850905516
Ln2 = 0.6931471805599453
Ln10 = 2.302585092994046
# MaxInt is the largest integer that fits in a tau int, MinInt the smallest.
MaxInt = 9223372036854775807
MinInt = -9223372036854775807 - 1
Sqrt = ffi.Func(libm.sqrt, "double sqrt(double)")
Cbrt = ffi.Func(libm.cbrt, "double cbrt(double)")
Exp = ffi.Func(libm.exp, "double exp(double)")
Log = ffi.Func(libm.log, "double log(double)")
Log2 = ffi.Func(libm.log2, "double log2(double)")
Log10 = ffi.Func(libm.log10, "double log10(double)")
Sin = ffi.Func(libm.sin, "double sin(double)")
Cos = ffi.Func(libm.cos, "double cos(double)")
Tan = ffi.Func(libm.tan, "double tan(double)")
Asin = ffi.Func(libm.asin, "double asin(double)")
Acos = ffi.Func(libm.acos, "double acos(double)")
Atan = ffi.Func(libm.atan, "double atan(double)")
Sinh = ffi.Func(libm.sinh, "double sinh(double)")
Cosh = ffi.Func(libm.cosh, "double cosh(double)")
Tanh = ffi.Func(libm.tanh, "double tanh(double)")
Floor = ffi.Func(libm.floor, "double floor(double)")
Ceil = ffi.Func(libm.ceil, "double ceil(double)")
Round = ffi.Func(libm.round, "double round(double)")
Trunc = ffi.Func(libm.trunc, "double trunc(double)")
Pow = ffi.Func(libm.pow, "double pow(double, double)")
Atan2 = ffi.Func(libm.atan2, "double atan2(double, double)")
Mod = ffi.Func(libm.fmod, "double fmod(double, double)")
Hypot = ffi.Func(libm.hypot, "double hypot(double, double)")
# Abs is the absolute value, an integer staying an integer: it is the one case
# where going through a float would lose the largest values.
Abs = fn(x) { if x < 0 { -x } else { x } }
# Inf returns positive infinity, or negative when sign is negative. A division
# is how a float says it, and there is no function to ask for one.
Inf = fn(sign) {
if sign != null && sign < 0 {
return -1.0 / 0.0
}
return 1.0 / 0.0
}
# NaN returns a value that is not a number, and IsNaN is how to recognise one:
# != does not follow IEEE here, so x != x is not the test it is in C.
NaN = fn() { 0.0 / 0.0 }
# The two that C answers with an int, which here is a question with a yes or a
# no.
isnan = ffi.Func(libm.isnan, "int isnan(double)")
isinf = ffi.Func(libm.isinf, "int isinf(double)")
IsNaN = fn(x) { isnan(x) != 0 }
IsInf = fn(x) { isinf(x) != 0 }
Min = fn(a, b) { if a < b { a } else { b } }
Max = fn(a, b) { if a > b { a } else { b } }
# Signum is -1, 0 or 1, following the sign of x.
Signum = fn(x) {
if x > 0 {
return 1
}
if x < 0 {
return -1
}
return 0
}