blob: 8fe3f0d68696ae5a5a849a2fb22dee387a642387 (
plain) (
blame)
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
|
package main
import (
"fmt"
"math"
)
// parseFunction returns nil is fn is not a valid function.
func parseFunction(fn string) func(Calculator) {
switch fn {
case "sin", "cos", "tan":
return trig(fn)
case "asin", "acos", "atan":
return invTrig(fn)
}
return nil
}
// trig returns a closure that performs the trig function specified by fn.
// Panics if fn is not one of "sin", "cos" or "tan".
func trig(fn string) func(Calculator) {
return func(c Calculator) {
if len(c.stack) <= 0 {
return
}
v := &c.stack[len(c.stack)-1]
// The math package expects arguments to trig functions to be in radians.
if c.anglem == modeDeg {
*v = radians(*v)
}
switch fn {
case "sin":
*v = math.Sin(*v)
case "cos":
*v = math.Cos(*v)
case "tan":
*v = math.Tan(*v)
default:
panic(fmt.Sprintf("invalid trig function: '%s'", fn))
}
}
}
// invTrig returns a closure that performs the inverse trig function specified
// by fn. Panics if fn is not one of "asin", "acos" or "atan".
func invTrig(fn string) func(Calculator) {
return func(c Calculator) {
if len(c.stack) <= 0 {
return
}
v := &c.stack[len(c.stack)-1]
switch fn {
case "asin":
*v = math.Asin(*v)
case "acos":
*v = math.Acos(*v)
case "atan":
*v = math.Atan(*v)
default:
panic(fmt.Sprintf("invalid inverse trig function: '%s'", fn))
}
if c.anglem == modeDeg {
*v = degrees(*v)
}
}
}
// radians converts degrees to radians.
func radians(deg float64) float64 {
return deg * math.Pi / 180.0
}
// degrees converts radians to degrees.
func degrees(rad float64) float64 {
return rad * 180 / math.Pi
}
|