[function](round) compute accurate round value by decimal#14946
[function](round) compute accurate round value by decimal#14946Gabriel39 merged 5 commits intoapache:masterfrom
Conversation
be/src/vec/functions/round.h
Outdated
| return x / scale * scale; | ||
| } | ||
| case RoundingMode::Floor: { | ||
| if (x < 0) x -= scale - 1; |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| if (x < 0) x -= scale - 1; | |
| if (x < 0) { x -= scale - 1; | |
| } |
be/src/vec/functions/round.h
Outdated
| return x / scale * scale; | ||
| } | ||
| case RoundingMode::Ceil: { | ||
| if (x >= 0) x += scale - 1; |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| if (x >= 0) x += scale - 1; | |
| if (x >= 0) { x += scale - 1; | |
| } |
be/src/vec/functions/round.h
Outdated
| return x / scale * scale; | ||
| } | ||
| case RoundingMode::Round: { | ||
| if (x < 0) x -= scale; |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| if (x < 0) x -= scale; | |
| if (x < 0) { x -= scale; | |
| } |
be/src/vec/functions/round.h
Outdated
| break; | ||
| case TieBreakingMode::Bankers: { | ||
| T quotient = (x + scale / 2) / scale; | ||
| if (quotient * scale == x + scale / 2) |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| if (quotient * scale == x + scale / 2) | |
| if (quotient * scale == x + scale / 2) { |
be/src/vec/functions/round.h:92:
- else
+ } else
be/src/vec/functions/round.h
Outdated
| if (quotient * scale == x + scale / 2) | ||
| // round half to even | ||
| x = ((quotient + (x < 0)) & ~1) * scale; | ||
| else |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| else | |
| else { |
be/src/vec/functions/round.h:94:
- x = quotient * scale;
+ x = quotient * scale;
+ }| } | ||
|
|
||
| bool use_default_implementation_for_constants() const override { return true; } | ||
| ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; } |
There was a problem hiding this comment.
warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
^| } | ||
|
|
||
| bool use_default_implementation_for_constants() const override { return true; } | ||
| ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; } |
There was a problem hiding this comment.
warning: braces around scalar initializer [clang-diagnostic-braced-scalar-init]
| ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; } | |
| ColumnNumbers get_arguments_that_are_always_constant() const override { return 1; } |
| bool use_default_implementation_for_constants() const override { return true; } | ||
| ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; } | ||
|
|
||
| Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
There was a problem hiding this comment.
warning: unknown type name 'Block' [clang-diagnostic-error]
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
^| bool use_default_implementation_for_constants() const override { return true; } | ||
| ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; } | ||
|
|
||
| Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
There was a problem hiding this comment.
warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
^|
|
||
| Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, | ||
| size_t result, size_t /*input_rows_count*/) override { | ||
| const ColumnWithTypeAndName& column = block.get_by_position(arguments[0]); |
There was a problem hiding this comment.
warning: unknown type name 'ColumnWithTypeAndName' [clang-diagnostic-error]
const ColumnWithTypeAndName& column = block.get_by_position(arguments[0]);
^|
TeamCity pipeline, clickbench performance test result: |
| return x / scale * scale; | ||
| } | ||
| case RoundingMode::Floor: { | ||
| if (x < 0) { |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| if (x < 0) { | |
| if (x < 0) { x -= scale - 1; | |
| } |
| x -= scale - 1; | ||
| } | ||
| return x / scale * scale; | ||
| } |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| } | |
| if (x >= 0) { x += scale - 1; | |
| } |
| case RoundingMode::Ceil: { | ||
| if (x >= 0) { | ||
| x += scale - 1; | ||
| } |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| } | |
| if (x < 0) { x -= scale; | |
| } |
| if (x < 0) { | ||
| x -= scale; | ||
| } | ||
| switch (tie_breaking_mode) { |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| switch (tie_breaking_mode) { | |
| if (quotient * scale == x + scale / 2) { |
be/src/vec/functions/round.h:92:
- else
+ } else| switch (tie_breaking_mode) { | ||
| case TieBreakingMode::Auto: | ||
| x = (x + scale / 2) / scale * scale; | ||
| break; |
There was a problem hiding this comment.
warning: statement should be inside braces [readability-braces-around-statements]
| break; | |
| else { |
be/src/vec/functions/round.h:94:
- x = quotient * scale;
+ x = quotient * scale;
+ }|
|
||
| Int64 scale64 = scale_field.get<Int64>(); | ||
| if (scale64 > std::numeric_limits<Int16>::max() || | ||
| scale64 < std::numeric_limits<Int16>::min()) { |
There was a problem hiding this comment.
warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]
ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; }
^|
|
||
| Int64 scale64 = scale_field.get<Int64>(); | ||
| if (scale64 > std::numeric_limits<Int16>::max() || | ||
| scale64 < std::numeric_limits<Int16>::min()) { |
There was a problem hiding this comment.
warning: braces around scalar initializer [clang-diagnostic-braced-scalar-init]
| scale64 < std::numeric_limits<Int16>::min()) { | |
| ColumnNumbers get_arguments_that_are_always_constant() const override { return 1; } |
| if (scale64 > std::numeric_limits<Int16>::max() || | ||
| scale64 < std::numeric_limits<Int16>::min()) { | ||
| return Status::InvalidArgument("Scale argument for function {} is too large: {}", name, | ||
| scale64); |
There was a problem hiding this comment.
warning: unknown type name 'Block' [clang-diagnostic-error]
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
^| if (scale64 > std::numeric_limits<Int16>::max() || | ||
| scale64 < std::numeric_limits<Int16>::min()) { | ||
| return Status::InvalidArgument("Scale argument for function {} is too large: {}", name, | ||
| scale64); |
There was a problem hiding this comment.
warning: unknown type name 'ColumnNumbers' [clang-diagnostic-error]
Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
^| return Status::InvalidArgument("Scale argument for function {} is too large: {}", name, | ||
| scale64); | ||
| } | ||
|
|
There was a problem hiding this comment.
warning: unknown type name 'ColumnWithTypeAndName' [clang-diagnostic-error]
const ColumnWithTypeAndName& column = block.get_by_position(arguments[0]);
^
be/src/vec/functions/round.h
Outdated
| static size_t prepare(size_t scale) { return scale; } | ||
|
|
||
| /// Integer overflow is Ok. | ||
| static ALWAYS_INLINE T computeImpl(T x, T scale) { |
|
PR approved by at least one committer and no changes requested. |
|
PR approved by anyone and no changes requested. |
|
round(16.025,2) should be 16.03 not 16.03000 |
Proposed changes
before:

after:

Problem summary
Describe your changes.
Checklist(Required)
Further comments
If this is a relatively large or complex change, kick off the discussion at dev@doris.apache.org by explaining why you chose the solution you did and what alternatives you considered, etc...