1
0
Fork 0
gnums/calc.go

249 lines
3.4 KiB
Go

package main
import (
"fmt"
"math"
"strconv"
"strings"
)
type stack struct {
ptr int
data [100]float64
}
func (s *stack) String() string {
if stackStyle == TopOfStack {
if s.ptr < 0 {
return ""
}
return strconv.FormatFloat(s.data[s.ptr], 'f', -1, 64)
} else if stackStyle == TopThree {
strArr := make([]string, 0, 3)
if stackSort == Dsc {
target := s.ptr-2
if target < 0 {
target = 0
}
for i := s.ptr; i >= target; i-- {
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
}
} else {
for i := range s.data {
if i >= 3 {
break
}
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
}
}
return strings.Join(strArr, ",\n")
} else {
format := "[%d]{\n\t%s\n}"
strArr := make([]string, 0, s.ptr+1)
if stackSort == Dsc {
for i := s.ptr; i >= 0; i-- {
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
}
} else {
for i := range s.data {
if i > s.ptr {
break
}
strArr = append(strArr, strconv.FormatFloat(s.data[i], 'f', -1, 64))
}
}
return fmt.Sprintf(format, s.ptr+1, strings.Join(strArr, ",\n\t"))
}
}
func (s *stack) Push(v float64) {
if s.ptr >= 99 {
s.Clear()
return
}
s.ptr++
s.data[s.ptr] = v
}
func (s *stack) Pop() (float64, error) {
if s.ptr < 0 {
s.Clear()
return 0.0, fmt.Errorf("Stack underflow")
}
s.ptr--
return s.data[s.ptr+1], nil
}
func (s *stack) Clear() {
s.ptr = -1
}
func (s stack) Len() int {
return s.ptr+1
}
func (s stack) Peek() float64 {
if s.Len() > 0 {
return s.data[s.ptr]
}
return 0.0
}
func (s *stack) Add() {
n2, err := s.Pop()
if err != nil {
return
}
n1, err := s.Pop()
if err != nil {
return
}
s.Push(n1+n2)
}
func (s *stack) Sub() {
n2, err := s.Pop()
if err != nil {
return
}
n1, err := s.Pop()
if err != nil {
return
}
s.Push(n1-n2)
}
func (s *stack) Mul() {
n2, err := s.Pop()
if err != nil {
return
}
n1, err := s.Pop()
if err != nil {
return
}
s.Push(n1*n2)
}
func (s *stack) Div() {
n2, err := s.Pop()
if err != nil {
return
}
n1, err := s.Pop()
if err != nil {
return
}
s.Push(n1/n2)
}
func (s *stack) Pow() {
exp, err := s.Pop()
if err != nil {
return
}
base, err := s.Pop()
if err != nil {
return
}
s.Push(math.Pow(base, exp))
}
func (s *stack) Floor() {
n, err := s.Pop()
if err != nil {
return
}
s.Push(math.Floor(n))
}
func (s *stack) Ceil() {
n, err := s.Pop()
if err != nil {
return
}
s.Push(math.Ceil(n))
}
func (s *stack) Round() {
decimals, err := s.Pop()
if err != nil {
return
}
num, err := s.Pop()
if err != nil {
return
}
s.Push(math.Round(num*math.Pow(10, decimals)) / math.Pow(10, decimals))
}
func (s *stack) Abs() {
n, err := s.Pop()
if err != nil {
return
}
if n < 0 {
s.Push(n*-1)
} else {
s.Push(n)
}
}
func (s *stack) Inv() {
n, err := s.Pop()
if err != nil {
return
}
s.Push(n*-1)
}
func (s *stack) Sqt() {
n, err := s.Pop()
if err != nil {
return
}
s.Push(math.Sqrt(n))
}
func (s *stack) Dup() {
val, err := s.Pop()
if err != nil {
return
}
s.Push(val)
s.Push(val)
}
func (s *stack) Ovr() {
tos, err := s.Pop()
if err != nil {
return
}
cpy, err := s.Pop()
if err != nil {
return
}
s.Push(cpy)
s.Push(tos)
s.Push(cpy)
}
func (s *stack) Swp() {
tos, err := s.Pop()
if err != nil {
return
}
newTos, err := s.Pop()
if err != nil {
return
}
s.Push(tos)
s.Push(newTos)
}
func (s *stack) Drp() {
s.Pop()
}