Skip to content

Commit e5ae2cf

Browse files
committed
Rewrite division
1 parent 5cbc75d commit e5ae2cf

File tree

1 file changed

+20
-21
lines changed

1 file changed

+20
-21
lines changed

cpp/src/arrow/util/int_util_overflow.h

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,15 @@ namespace internal {
4040
return !check_##_op_name##_##_type##_##_type(u, v, out); \
4141
}
4242

43-
#define SAFE_INT_OPS_WITH_OVERFLOW(_func_name, _psnip_op) \
44-
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _psnip_op, int32_t, int32) \
45-
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _psnip_op, int64_t, int64) \
46-
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _psnip_op, uint32_t, uint32) \
47-
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _psnip_op, uint64_t, uint64)
43+
#define SAFE_INT_OPS_WITH_OVERFLOW(_func_name, _op_name) \
44+
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _op_name, int32_t, int32) \
45+
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _op_name, int64_t, int64) \
46+
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _op_name, uint32_t, uint32) \
47+
SAFE_INT_OP_WITH_OVERFLOW(_func_name, _op_name, uint64_t, uint64)
4848

4949
SAFE_INT_OPS_WITH_OVERFLOW(SafeIntAddWithOverflow, add)
5050
SAFE_INT_OPS_WITH_OVERFLOW(SafeIntSubtractWithOverflow, sub)
5151
SAFE_INT_OPS_WITH_OVERFLOW(SafeIntMultiplyWithOverflow, mul)
52-
SAFE_INT_OPS_WITH_OVERFLOW(SafeIntDivideWithOverflow, div)
5352

5453
#undef SAFE_INT_OP_WITH_OVERFLOW
5554
#undef SAFE_INT_OPS_WITH_OVERFLOW
@@ -77,8 +76,8 @@ template <typename Int>
7776
return __builtin_add_overflow(u, v, out);
7877
#else
7978
if constexpr (sizeof(Int) < 4) {
80-
auto r =
81-
static_cast<upscaled_int32_t<Int> >(u) + static_cast<upscaled_int32_t<Int> >(v);
79+
using UpscaledInt = upscaled_int32_t<Int>;
80+
auto r = static_cast<UpscaledInt>(u) + static_cast<UpscaledInt>(v);
8281
*out = static_cast<Int>(r);
8382
return r != *out;
8483
} else {
@@ -93,8 +92,8 @@ template <typename Int>
9392
return __builtin_sub_overflow(u, v, out);
9493
#else
9594
if constexpr (sizeof(Int) < 4) {
96-
auto r =
97-
static_cast<upscaled_int32_t<Int> >(u) - static_cast<upscaled_int32_t<Int> >(v);
95+
using UpscaledInt = upscaled_int32_t<Int>;
96+
auto r = static_cast<UpscaledInt>(u) - static_cast<UpscaledInt>(v);
9897
*out = static_cast<Int>(r);
9998
return r != *out;
10099
} else {
@@ -109,8 +108,8 @@ template <typename Int>
109108
return __builtin_mul_overflow(u, v, out);
110109
#else
111110
if constexpr (sizeof(Int) < 4) {
112-
auto r =
113-
static_cast<upscaled_int32_t<Int> >(u) * static_cast<upscaled_int32_t<Int> >(v);
111+
using UpscaledInt = upscaled_int32_t<Int>;
112+
auto r = static_cast<UpscaledInt>(u) * static_cast<UpscaledInt>(v);
114113
*out = static_cast<Int>(r);
115114
return r != *out;
116115
} else {
@@ -125,15 +124,15 @@ template <typename Int>
125124
*out = Int{};
126125
return true;
127126
}
128-
if constexpr (sizeof(Int) < 4) {
129-
using UpscaledInt = upscaled_int32_t<Int>;
130-
UpscaledInt r;
131-
bool error = SafeIntDivideWithOverflow(UpscaledInt{u}, UpscaledInt{v}, &r);
132-
*out = static_cast<Int>(r);
133-
return error || r != *out;
134-
} else {
135-
return SafeIntDivideWithOverflow(u, v, out);
127+
if constexpr (std::is_signed_v<Int>) {
128+
constexpr auto kMin = std::numeric_limits<Int>::min();
129+
if (u == kMin && v == -1) {
130+
*out = kMin;
131+
return true;
132+
}
136133
}
134+
*out = u / v;
135+
return false;
137136
}
138137

139138
// Define non-generic versions of the above so as to benefit from automatic
@@ -142,7 +141,7 @@ template <typename Int>
142141

143142
#define NON_GENERIC_OP_WITH_OVERFLOW(_func_name, _c_type) \
144143
[[nodiscard]] inline bool _func_name(_c_type u, _c_type v, _c_type* out) { \
145-
return _func_name##Generic(u, v, out); \
144+
return ARROW_PREDICT_FALSE(_func_name##Generic(u, v, out)); \
146145
}
147146

148147
#define NON_GENERIC_OPS_WITH_OVERFLOW(_func_name) \

0 commit comments

Comments
 (0)