From 1d3d1f2e2ca0a46a892eb20c3f68571c46fcf81f Mon Sep 17 00:00:00 2001 From: Jim Larson Date: Tue, 13 Apr 2021 20:39:23 -0700 Subject: [PATCH 1/2] Convert double to integer via truncation. Matches behavior of C, Go, and Java. Introduce a round() function for round-half-away like GoogleSQL. --- doc/langdef.md | 18 +++++- tests/simple/testdata/conversions.textproto | 33 +++++------ tests/simple/testdata/fp_math.textproto | 61 +++++++++++++++++++++ 3 files changed, 91 insertions(+), 21 deletions(-) diff --git a/doc/langdef.md b/doc/langdef.md index c34d690f..b23ede34 100644 --- a/doc/langdef.md +++ b/doc/langdef.md @@ -2070,7 +2070,8 @@ See [cel-go/issues/9](https://github.com/google/cel-go/issues/9). (double) -> int - type conversion + Type conversion. Rounds toward zero, then errors if result is out of + range. See also round(). @@ -2151,6 +2152,18 @@ See [cel-go/issues/9](https://github.com/google/cel-go/issues/9). type denotation + + + round + + + (double) -> int + + + Rounds half away (i.e. round(1.5) is 2, round(-1.5) is -2). Error if + result is out of range. + + size @@ -2295,7 +2308,8 @@ See [cel-go/issues/9](https://github.com/google/cel-go/issues/9). (double) -> uint - type conversion + Type conversion. Rounds toward zero, then errors if result is out of + range. diff --git a/tests/simple/testdata/conversions.textproto b/tests/simple/testdata/conversions.textproto index e9d09092..1f4c8752 100644 --- a/tests/simple/testdata/conversions.textproto +++ b/tests/simple/testdata/conversions.textproto @@ -151,24 +151,24 @@ section { value: { int64_value: -123 } } test { - name: "double_nearest" + name: "double_truncate" expr: "int(1.9)" - value: { int64_value: 2 } + value: { int64_value: 1 } } test { - name: "double_nearest_neg" + name: "double_truncate_neg" expr: "int(-7.9)" - value: { int64_value: -8 } + value: { int64_value: -7 } } test { - name: "double_half_away_pos" + name: "double_half_pos" expr: "int(11.5)" - value: { int64_value: 12 } + value: { int64_value: 11 } } test { - name: "double_half_away_neg" + name: "double_half_neg" expr: "int(-3.5)" - value: { int64_value: -4 } + value: { int64_value: -3 } } test { name: "double_range" @@ -407,23 +407,18 @@ section { value: { uint64_value: 3 } } test { - name: "double_nearest_int" - expr: "int(1.9)" - value: { int64_value: 2 } - } - test { - name: "double_nearest" + name: "double_truncate" expr: "uint(1.9)" - value: { uint64_value: 2 } + value: { uint64_value: 1 } } test { - name: "double_half_away" + name: "double_half" expr: "uint(25.5)" - value: { uint64_value: 26 } + value: { uint64_value: 25 } } test { - name: "double_range_beyond_int" - description: "Checks conversion of integer outside int range." + name: "double_range_beyond_uint" + description: "Checks conversion of integer outside uint range." expr: "uint(1e19)" value: { uint64_value: 10000000000000000000 } } diff --git a/tests/simple/testdata/fp_math.textproto b/tests/simple/testdata/fp_math.textproto index 38a3eae2..eebebebb 100644 --- a/tests/simple/testdata/fp_math.textproto +++ b/tests/simple/testdata/fp_math.textproto @@ -162,3 +162,64 @@ section { value: {double_value: 0} } } +section { + name: "round" + description: "Tests for round()." + test { + name: "zero" + expr: "round(0.0)" + value { int64_value: 0 } + } + test { + name: "zero_neg" + expr: "round(-0.0)" + value { int64_value: 0 } + } + test { + name: "exact" + expr: "round(1.0)" + value { int64_value: 1 } + } + test { + name: "exact_neg" + expr: "round(-3.0)" + value { int64_value: -3 } + } + test { + name: "small_frac_pos" + expr: "round(3.1416)" + value { int64_value: 3 } + } + test { + name: "small_frac_neg" + expr: "round(-27.4)" + value { int64_value: -27 } + } + test { + name: "half_pos" + expr: "round(32.5)" + value { int64_value: 33 } + } + test { + name: "half_neg" + expr: "round(-17.5)" + value { int64_value: -18 } + } + test { + name: "big_frac_pos" + expr: "round(2.71828)" + value { int64_value: 3 } + } + test { + name: "big_frac_neg" + expr: "round(-7.8)" + value { int64_value: -8 } + } + test { + name: "range" + expr: "round(1e99)" + eval_error { + errors { message: "range" } + } + } +} From 931f7cf949a83c0adf8a8ca39cdeb43ba2a18364 Mon Sep 17 00:00:00 2001 From: Jim Larson Date: Sat, 17 Apr 2021 20:03:49 -0700 Subject: [PATCH 2/2] Address review feedback. Defer round() until another PR. --- doc/langdef.md | 14 +----- tests/simple/testdata/fp_math.textproto | 61 ------------------------- 2 files changed, 1 insertion(+), 74 deletions(-) diff --git a/doc/langdef.md b/doc/langdef.md index b23ede34..de8431a9 100644 --- a/doc/langdef.md +++ b/doc/langdef.md @@ -2071,7 +2071,7 @@ See [cel-go/issues/9](https://github.com/google/cel-go/issues/9). Type conversion. Rounds toward zero, then errors if result is out of - range. See also round(). + range. @@ -2152,18 +2152,6 @@ See [cel-go/issues/9](https://github.com/google/cel-go/issues/9). type denotation - - - round - - - (double) -> int - - - Rounds half away (i.e. round(1.5) is 2, round(-1.5) is -2). Error if - result is out of range. - - size diff --git a/tests/simple/testdata/fp_math.textproto b/tests/simple/testdata/fp_math.textproto index eebebebb..38a3eae2 100644 --- a/tests/simple/testdata/fp_math.textproto +++ b/tests/simple/testdata/fp_math.textproto @@ -162,64 +162,3 @@ section { value: {double_value: 0} } } -section { - name: "round" - description: "Tests for round()." - test { - name: "zero" - expr: "round(0.0)" - value { int64_value: 0 } - } - test { - name: "zero_neg" - expr: "round(-0.0)" - value { int64_value: 0 } - } - test { - name: "exact" - expr: "round(1.0)" - value { int64_value: 1 } - } - test { - name: "exact_neg" - expr: "round(-3.0)" - value { int64_value: -3 } - } - test { - name: "small_frac_pos" - expr: "round(3.1416)" - value { int64_value: 3 } - } - test { - name: "small_frac_neg" - expr: "round(-27.4)" - value { int64_value: -27 } - } - test { - name: "half_pos" - expr: "round(32.5)" - value { int64_value: 33 } - } - test { - name: "half_neg" - expr: "round(-17.5)" - value { int64_value: -18 } - } - test { - name: "big_frac_pos" - expr: "round(2.71828)" - value { int64_value: 3 } - } - test { - name: "big_frac_neg" - expr: "round(-7.8)" - value { int64_value: -8 } - } - test { - name: "range" - expr: "round(1e99)" - eval_error { - errors { message: "range" } - } - } -}