Skip to content

Commit 833023f

Browse files
resetiusGazizonoki
authored andcommitted
Moved commit "Block decimal kernels (*, /, %)" from ydb repo
1 parent 4e970bf commit 833023f

File tree

1 file changed

+128
-2
lines changed

1 file changed

+128
-2
lines changed

src/library/yql_common/decimal/yql_decimal.h

Lines changed: 128 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,6 @@ struct TDecimal {
194194
return *this;
195195
}
196196

197-
// TODO: implement '-' and '%'
198-
199197
friend TDecimal operator+(TDecimal left, TDecimal right) {
200198
left += right;
201199
return left;
@@ -212,5 +210,133 @@ struct TDecimal {
212210
}
213211
};
214212

213+
template<typename TRight>
214+
class TDecimalMultiplicator {
215+
protected:
216+
const TInt128 Bound;
217+
218+
public:
219+
TDecimalMultiplicator(
220+
ui8 precision,
221+
[[maybe_unused]] ui8 scale = 0)
222+
: Bound(GetDivider(precision))
223+
{
224+
}
225+
226+
TInt128 Do(TInt128 left, TRight right) const {
227+
TInt128 mul = Mul(left, right);
228+
229+
if (mul > -Bound && mul < +Bound)
230+
return mul;
231+
232+
return IsNan(mul) ? Nan() : (mul > 0 ? +Inf() : -Inf());
233+
}
234+
};
235+
236+
template<>
237+
class TDecimalMultiplicator<TInt128> {
238+
protected:
239+
const TInt128 Bound;
240+
const TInt128 Divider;
241+
242+
public:
243+
TDecimalMultiplicator(
244+
ui8 precision,
245+
ui8 scale)
246+
: Bound(GetDivider(precision))
247+
, Divider(GetDivider(scale))
248+
{ }
249+
250+
TInt128 Do(TInt128 left, TInt128 right) const {
251+
TInt128 mul = Divider > 1 ?
252+
MulAndDivNormalDivider(left, right, Divider):
253+
Mul(left, right);
254+
255+
if (mul > -Bound && mul < +Bound)
256+
return mul;
257+
258+
return IsNan(mul) ? Nan() : (mul > 0 ? +Inf() : -Inf());
259+
}
260+
};
261+
262+
template<typename TRight>
263+
class TDecimalDivisor {
264+
public:
265+
TDecimalDivisor(
266+
[[maybe_unused]] ui8 precision = 0,
267+
[[maybe_unused]] ui8 scale = 0)
268+
{
269+
}
270+
271+
TInt128 Do(TInt128 left, TRight right) const {
272+
return Div(left, right);
273+
}
274+
};
275+
276+
template<>
277+
class TDecimalDivisor<TInt128> {
278+
protected:
279+
const TInt128 Bound;
280+
const TInt128 Divider;
281+
282+
public:
283+
TDecimalDivisor(
284+
ui8 precision,
285+
ui8 scale)
286+
: Bound(GetDivider(precision))
287+
, Divider(GetDivider(scale))
288+
{ }
289+
290+
TInt128 Do(TInt128 left, TInt128 right) const {
291+
TInt128 div = MulAndDivNormalMultiplier(left, Divider, right);
292+
if (div > -Bound && div < +Bound) {
293+
return div;
294+
}
295+
296+
return IsNan(div) ? Nan() : (div > 0 ? +Inf() : -Inf());
297+
}
298+
};
299+
300+
template<typename TRight>
301+
class TDecimalRemainder {
302+
protected:
303+
const TInt128 Bound;
304+
const TInt128 Divider;
305+
306+
public:
307+
TDecimalRemainder(
308+
ui8 precision,
309+
ui8 scale)
310+
: Bound(NYql::NDecimal::GetDivider(precision - scale))
311+
, Divider(NYql::NDecimal::GetDivider(scale))
312+
{ }
313+
314+
TInt128 Do(TInt128 left, TRight right) const {
315+
if constexpr (std::is_signed<TRight>::value) {
316+
if (right >= +Bound || right <= -Bound)
317+
return left;
318+
} else {
319+
if (right >= Bound)
320+
return left;
321+
}
322+
323+
return Mod(left, Mul(Divider, right));
324+
}
325+
};
326+
327+
template<>
328+
class TDecimalRemainder<TInt128> {
329+
public:
330+
TDecimalRemainder(
331+
[[maybe_unused]] ui8 precision = 0,
332+
[[maybe_unused]] ui8 scale = 0)
333+
{
334+
}
335+
336+
TInt128 Do(TInt128 left, TInt128 right) const {
337+
return NYql::NDecimal::Mod(left, right);
338+
}
339+
};
340+
215341
}
216342
}

0 commit comments

Comments
 (0)