diff --git a/assets/calc/large-ints.yml b/assets/calc/large-ints.yml new file mode 100644 index 00000000..509990cd --- /dev/null +++ b/assets/calc/large-ints.yml @@ -0,0 +1,2 @@ +int: (( calc "90 * 86400" )) +float: (( calc "(90 * 86400) + 0.1" )) diff --git a/ci/release_notes.md b/ci/release_notes.md new file mode 100644 index 00000000..b6d82479 --- /dev/null +++ b/ci/release_notes.md @@ -0,0 +1,9 @@ +# Bug Fixes + +- Fixed `((calc))` to output integer values for its output, when + the result is a large integer. Previously, it was treated as a float, + and converted to scientific notation by the YAML marshaler. Fixes #286. + +# Acknowledgements + +Thanks @jhunt for finding and reporting the issue! diff --git a/cmd/spruce/main_test.go b/cmd/spruce/main_test.go index 50509849..17bb1951 100644 --- a/cmd/spruce/main_test.go +++ b/cmd/spruce/main_test.go @@ -1298,6 +1298,18 @@ z: `) So(stdout, ShouldEqual, "") }) + + Convey("Calc returns int64s if possible", func() { + os.Args = []string{"spruce", "merge", "--prune", "meta", "../../assets/calc/large-ints.yml"} + stdout = "" + stderr = "" + main() + So(stderr, ShouldEqual, "") + So(stdout, ShouldEqual, `float: 7.776e+06 +int: 7776000 + +`) + }) }) Convey("YAML output is ordered the same way each time (#184)", func() { diff --git a/op_calc.go b/op_calc.go index e65844f7..04546b48 100644 --- a/op_calc.go +++ b/op_calc.go @@ -86,6 +86,13 @@ func (CalcOperator) Run(ev *Evaluator, args []*Expr) (*Response, error) { return nil, evaluateError } + if resultFloat, ok := result.(float64); ok { + resultInt := int64(resultFloat) + if float64(resultInt) == resultFloat { + result = resultInt + } + } + DEBUG(" evaluated result: %v", result) return &Response{ Type: Replace,