mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Merge pull request #20067 from ClickHouse/mod-negative-type-promotion
Add type promotion for modulo of division of negative number
This commit is contained in:
commit
34151eea2c
@ -104,11 +104,16 @@ template <typename A, typename B> struct ResultOfIntegerDivision
|
|||||||
sizeof(A)>::Type;
|
sizeof(A)>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Division with remainder you get a number with the same number of bits as in divisor.
|
/** Division with remainder you get a number with the same number of bits as in divisor,
|
||||||
*/
|
* or larger in case of signed type.
|
||||||
|
*/
|
||||||
template <typename A, typename B> struct ResultOfModulo
|
template <typename A, typename B> struct ResultOfModulo
|
||||||
{
|
{
|
||||||
using Type0 = typename Construct<is_signed_v<A> || is_signed_v<B>, false, sizeof(B)>::Type;
|
static constexpr bool result_is_signed = is_signed_v<A>;
|
||||||
|
/// If modulo of division can yield negative number, we need larger type to accommodate it.
|
||||||
|
/// Example: toInt32(-199) % toUInt8(200) will return -199 that does not fit in Int8, only in Int16.
|
||||||
|
static constexpr size_t size_of_result = result_is_signed ? nextSize(sizeof(B)) : sizeof(B);
|
||||||
|
using Type0 = typename Construct<result_is_signed, false, size_of_result>::Type;
|
||||||
using Type = std::conditional_t<std::is_floating_point_v<A> || std::is_floating_point_v<B>, Float64, Type0>;
|
using Type = std::conditional_t<std::is_floating_point_v<A> || std::is_floating_point_v<B>, Float64, Type0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ TEST(NumberTraits, Others)
|
|||||||
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfFloatingPointDivision<DB::UInt16, DB::Int16>::Type()), "Float64");
|
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfFloatingPointDivision<DB::UInt16, DB::Int16>::Type()), "Float64");
|
||||||
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfFloatingPointDivision<DB::UInt32, DB::Int16>::Type()), "Float64");
|
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfFloatingPointDivision<DB::UInt32, DB::Int16>::Type()), "Float64");
|
||||||
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfIntegerDivision<DB::UInt8, DB::Int16>::Type()), "Int8");
|
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfIntegerDivision<DB::UInt8, DB::Int16>::Type()), "Int8");
|
||||||
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfModulo<DB::UInt32, DB::Int8>::Type()), "Int8");
|
ASSERT_EQ(getTypeString(DB::NumberTraits::ResultOfModulo<DB::UInt32, DB::Int8>::Type()), "UInt8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
-199
|
@ -0,0 +1 @@
|
|||||||
|
SELECT toInt32(-199) % 200;
|
Loading…
Reference in New Issue
Block a user