math-engine
math-engine copied to clipboard
浮点数相乘
0.7*360=251.99999999999997
这种好像没有做处理 :monocle_face:
可以使用 https://github.com/shopspring/decimal 做处理
package main
import (
"fmt"
"github.com/dengsgo/math-engine/engine"
"github.com/shopspring/decimal"
)
func main() {
s := "0.7*360"
// call top level function
r, err := engine.ParseAndExec(s)
if err != nil {
fmt.Println(err)
}
p, err := decimal.NewFromString(fmt.Sprintf("%f", r))
if err != nil {
panic(err)
}
fmt.Println(p) //252
}
本来想用 decimal 处理浮点数精度的问题,但是发现会损失精度
// Top level function
// Analytical expression and execution
// err is not nil if an error occurs (including arithmetic runtime errors)
func ParseAndExec(s string) (r float64, err error) {
toks, err := Parse(s)
if err != nil {
return 0, err
}
ast := NewAST(toks, s)
if ast.Err != nil {
return 0, ast.Err
}
ar := ast.ParseExpression()
if ast.Err != nil {
return 0, ast.Err
}
defer func() {
if e := recover(); e != nil {
err = e.(error)
}
}()
res, err := decimal.NewFromString(fmt.Sprintf("%f", ExprASTResult(ar)))
if err != nil {
return 0, err
}
r, _ = res.Float64()
return r, err
}
=== RUN TestParseAndExecSimple util_test.go:85: {3^4.5 140.29611541307906} ParseAndExec: 140.296115 util_test.go:85: {3.5^4.5 280.7412308013823} ParseAndExec: 280.741231 util_test.go:85: {pi 3.141592653589793} ParseAndExec: 3.141593 --- FAIL: TestParseAndExecSimple (0.00s)
FAIL
应该是要你保留多少个小数吧?这个看起来是被四舍五入了