add mathmatic calc
parent
cdf3a18981
commit
ad5c18667a
@ -0,0 +1,21 @@
|
||||
//+build linux darwin
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||
}
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(stat_t.Ctim)
|
||||
}
|
||||
|
||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||
return timespecToTime(stat_t.Atim)
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
// +build windows
|
||||
|
||||
package staros
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||
return time.Unix(0, d.CreationTime.Nanoseconds())
|
||||
}
|
||||
|
||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||
return time.Unix(0, d.LastAccessTime.Nanoseconds())
|
||||
}
|
@ -0,0 +1,294 @@
|
||||
package staros
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Calc(math string) (float64, error) {
|
||||
math = strings.Replace(math, " ", "", -1)
|
||||
math = strings.ToLower(math)
|
||||
if err := check(math); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return calc(math)
|
||||
}
|
||||
|
||||
func check(math string) error {
|
||||
math = strings.Replace(math, " ", "", -1)
|
||||
math = strings.ToLower(math)
|
||||
var bracketSum int
|
||||
var signReady bool
|
||||
for k, v := range math {
|
||||
if string([]rune{v}) == "(" {
|
||||
bracketSum++
|
||||
}
|
||||
if string([]rune{v}) == ")" {
|
||||
bracketSum--
|
||||
}
|
||||
if bracketSum < 0 {
|
||||
return fmt.Errorf("err at position %d.Reason is right bracket position not correct,except (", k)
|
||||
}
|
||||
if containSign(string([]rune{v})) {
|
||||
if signReady {
|
||||
if string([]rune{v}) != "+" && string([]rune{v}) != "-" {
|
||||
return fmt.Errorf("err at position %d.Reason is sign %s not correct", k, string([]rune{v}))
|
||||
}
|
||||
signReady = false
|
||||
} else {
|
||||
signReady = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if bracketSum != 0 {
|
||||
return fmt.Errorf("Error:right bracket is not equal as left bracket")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func calc(math string) (float64, error) {
|
||||
var bracketLeft int
|
||||
var bracketRight int
|
||||
var DupStart int = -1
|
||||
for pos, str := range math {
|
||||
if string(str) == "(" {
|
||||
bracketLeft = pos
|
||||
}
|
||||
if string(str) == ")" {
|
||||
bracketRight = pos
|
||||
break
|
||||
}
|
||||
}
|
||||
if bracketRight == 0 && bracketLeft != 0 || (bracketLeft > bracketRight) {
|
||||
return 0, fmt.Errorf("Error:bracket not correct at %d ,except )", bracketLeft)
|
||||
}
|
||||
if bracketRight == 0 && bracketLeft == 0 {
|
||||
return calcLong(math)
|
||||
}
|
||||
line := math[bracketLeft+1 : bracketRight]
|
||||
num, err := calcLong(line)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for i := bracketLeft - 1; i >= 0; i-- {
|
||||
if !containSign(math[i : i+1]) {
|
||||
DupStart = i
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if DupStart != -1 {
|
||||
sign := math[DupStart:bracketLeft]
|
||||
num, err := calcDuaFloat(sign, num)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
math = math[:DupStart] + fmt.Sprintf("%.15f", num) + math[bracketRight+1:]
|
||||
DupStart = -1
|
||||
} else {
|
||||
math = math[:bracketLeft] + fmt.Sprintf("%.15f", num) + math[bracketRight+1:]
|
||||
}
|
||||
return calc(math)
|
||||
}
|
||||
|
||||
func calcLong(str string) (float64, error) {
|
||||
var sigReady bool = false
|
||||
var sigApply bool = false
|
||||
var numPool []float64
|
||||
var operPool []string
|
||||
var numStr string
|
||||
var oper string
|
||||
if str[0:1] == "+" || str[0:1] == "-" {
|
||||
sigReady = true
|
||||
}
|
||||
for _, stp := range str {
|
||||
if sigReady && containSign(string(stp)) {
|
||||
sigReady = false
|
||||
sigApply = true
|
||||
oper = string(stp)
|
||||
continue
|
||||
}
|
||||
if !containSign(string(stp)) {
|
||||
sigReady = false
|
||||
numStr = string(append([]rune(numStr), stp))
|
||||
continue
|
||||
}
|
||||
if !sigReady {
|
||||
sigReady = true
|
||||
}
|
||||
if sigApply {
|
||||
num, err := calcDua(oper, numStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sigApply = false
|
||||
numPool = append(numPool, num)
|
||||
} else {
|
||||
num, err := parseNumbic(numStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
numPool = append(numPool, num)
|
||||
}
|
||||
numStr = ""
|
||||
operPool = append(operPool, string(stp))
|
||||
}
|
||||
if sigApply {
|
||||
num, err := calcDua(oper, numStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
numPool = append(numPool, num)
|
||||
} else {
|
||||
num, err := parseNumbic(numStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
numPool = append(numPool, num)
|
||||
}
|
||||
return calcPool(numPool, operPool)
|
||||
}
|
||||
|
||||
func calcPool(numPool []float64, operPool []string) (float64, error) {
|
||||
if len(numPool) == 1 && len(operPool) == 0 {
|
||||
return numPool[0], nil
|
||||
}
|
||||
if len(numPool) < len(operPool) {
|
||||
return 0, errors.New(("Operate Signal Is too much"))
|
||||
}
|
||||
calcFunc := func(k int, v string) (float64, error) {
|
||||
num, err := calcSigFloat(numPool[k], v, numPool[k+1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
tmp := append(numPool[:k], num)
|
||||
numPool = append(tmp, numPool[k+2:]...)
|
||||
operPool = append(operPool[:k], operPool[k+1:]...)
|
||||
return calcPool(numPool, operPool)
|
||||
}
|
||||
for k, v := range operPool {
|
||||
if v == "^" {
|
||||
return calcFunc(k, v)
|
||||
}
|
||||
}
|
||||
for k, v := range operPool {
|
||||
if v == "*" || v == "/" {
|
||||
return calcFunc(k, v)
|
||||
}
|
||||
}
|
||||
for k, v := range operPool {
|
||||
return calcFunc(k, v)
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func calcSigFloat(floatA float64, b string, floatC float64) (float64, error) {
|
||||
switch b {
|
||||
case "+":
|
||||
return floatA + floatC, nil
|
||||
case "-":
|
||||
return floatA - floatC, nil
|
||||
case "*":
|
||||
return floatA * floatC, nil
|
||||
case "/":
|
||||
if floatC == 0 {
|
||||
return 0, errors.New("Divisor cannot be 0")
|
||||
}
|
||||
return floatA / floatC, nil
|
||||
case "^":
|
||||
return math.Pow(floatA, floatC), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unexpect method:%s", b)
|
||||
}
|
||||
|
||||
func calcSig(a, b, c string) (float64, error) {
|
||||
floatA, err := parseNumbic(a)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
floatC, err := parseNumbic(c)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return calcSigFloat(floatA, b, floatC)
|
||||
}
|
||||
|
||||
func calcDuaFloat(a string, floatB float64) (float64, error) {
|
||||
switch a {
|
||||
case "sin":
|
||||
return math.Sin(floatB), nil
|
||||
case "cos":
|
||||
return math.Cos(floatB), nil
|
||||
case "tan":
|
||||
return math.Tan(floatB), nil
|
||||
case "abs":
|
||||
return math.Abs(floatB), nil
|
||||
case "arcsin":
|
||||
return math.Asin(floatB), nil
|
||||
case "arccos":
|
||||
return math.Acos(floatB), nil
|
||||
case "arctan":
|
||||
return math.Atan(floatB), nil
|
||||
case "sqrt":
|
||||
return math.Sqrt(floatB), nil
|
||||
case "loge":
|
||||
return math.Log(floatB), nil
|
||||
case "log10":
|
||||
return math.Log10(floatB), nil
|
||||
case "log2":
|
||||
return math.Log2(floatB), nil
|
||||
case "floor":
|
||||
return math.Floor(floatB), nil
|
||||
case "ceil":
|
||||
return math.Ceil(floatB), nil
|
||||
case "round":
|
||||
return math.Round(floatB), nil
|
||||
case "trunc":
|
||||
return math.Trunc(floatB), nil
|
||||
case "+":
|
||||
return 0 + floatB, nil
|
||||
case "-":
|
||||
return 0 - floatB, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unexpect method:%s", a)
|
||||
}
|
||||
func calcDua(a, b string) (float64, error) {
|
||||
floatB, err := parseNumbic(b)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return calcDuaFloat(a, floatB)
|
||||
}
|
||||
|
||||
func parseNumbic(str string) (float64, error) {
|
||||
switch str {
|
||||
case "pi":
|
||||
return float64(math.Pi), nil
|
||||
case "e":
|
||||
return float64(math.E), nil
|
||||
default:
|
||||
return strconv.ParseFloat(str, 64)
|
||||
}
|
||||
}
|
||||
|
||||
func containSign(str string) bool {
|
||||
var sign []string = []string{"+", "-", "*", "/", "^"}
|
||||
for _, v := range sign {
|
||||
if str == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func contain(pool []string, str string) bool {
|
||||
for _, v := range pool {
|
||||
if v == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Loading…
Reference in New Issue