From 68c3af2eefd87ddb0c3f2672015238248b8be372 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Wed, 25 Mar 2020 14:03:55 -0400 Subject: [PATCH] function/stdlib: Preserve infinity for floor/ceil MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit floor(±infinity) and ceil(±infinity) would previously return the max/min limit of int64. This could lead to confusing behaviour. Instead, we want to pass through the infinite value without converting to integer. --- cty/function/stdlib/number.go | 6 ++++++ cty/function/stdlib/number_test.go | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/cty/function/stdlib/number.go b/cty/function/stdlib/number.go index 48438fe0..7bbe584b 100644 --- a/cty/function/stdlib/number.go +++ b/cty/function/stdlib/number.go @@ -375,6 +375,9 @@ var CeilFunc = function.New(&function.Spec{ if err := gocty.FromCtyValue(args[0], &val); err != nil { return cty.UnknownVal(cty.String), err } + if math.IsInf(val, 0) { + return cty.NumberFloatVal(val), nil + } return cty.NumberIntVal(int64(math.Ceil(val))), nil }, }) @@ -394,6 +397,9 @@ var FloorFunc = function.New(&function.Spec{ if err := gocty.FromCtyValue(args[0], &val); err != nil { return cty.UnknownVal(cty.String), err } + if math.IsInf(val, 0) { + return cty.NumberFloatVal(val), nil + } return cty.NumberIntVal(int64(math.Floor(val))), nil }, }) diff --git a/cty/function/stdlib/number_test.go b/cty/function/stdlib/number_test.go index a8e8420b..14d69bf8 100644 --- a/cty/function/stdlib/number_test.go +++ b/cty/function/stdlib/number_test.go @@ -2,6 +2,7 @@ package stdlib import ( "fmt" + "math" "math/big" "testing" @@ -806,6 +807,16 @@ func TestCeil(t *testing.T) { cty.NumberFloatVal(2), false, }, + { + cty.NumberFloatVal(math.Inf(1)), + cty.NumberFloatVal(math.Inf(1)), + false, + }, + { + cty.NumberFloatVal(math.Inf(-1)), + cty.NumberFloatVal(math.Inf(-1)), + false, + }, } for _, test := range tests { @@ -844,6 +855,16 @@ func TestFloor(t *testing.T) { cty.NumberFloatVal(1), false, }, + { + cty.NumberFloatVal(math.Inf(1)), + cty.NumberFloatVal(math.Inf(1)), + false, + }, + { + cty.NumberFloatVal(math.Inf(-1)), + cty.NumberFloatVal(math.Inf(-1)), + false, + }, } for _, test := range tests {