31#ifndef ETL_ROUNDED_INTEGRAL_DIVISION_INCLUDED
32#define ETL_ROUNDED_INTEGRAL_DIVISION_INCLUDED
43 namespace private_rounded_integral_division
50 ETL_CONSTEXPR
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value,
bool>::type are_same_sign(T a, T b) ETL_NOEXCEPT
52 return ((a ^ b) >= 0);
60 ETL_CONSTEXPR
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value,
bool>::type are_same_sign(T , T )
76 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_to_ceiling(T numerator,
80 const T remainder = numerator % denominator;
81 const T quotient = numerator / denominator;
90 return private_rounded_integral_division::are_same_sign(numerator, denominator) ? quotient + 1 : quotient;
102 template <
typename T1,
typename T2>
104 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
105 typename etl::common_type<T1, T2>::type>::type
106 divide_round_to_ceiling(T1 numerator, T2 denominator) ETL_NOEXCEPT
108 typedef typename etl::common_type<T1, T2>::type
type;
110 return divide_round_to_ceiling(
static_cast<type>(numerator),
static_cast<type>(denominator));
121 template <
typename T>
122 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_to_ceiling(T numerator,
126 const T remainder = numerator % denominator;
127 const T quotient = numerator / denominator;
130 return remainder == 0U ? quotient : quotient + 1U;
142 template <
typename T1,
typename T2>
144 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
145 typename etl::common_type<T1, T2>::type>::type
146 divide_round_to_ceiling(T1 numerator, T2 denominator) ETL_NOEXCEPT
148 typedef typename etl::common_type<T1, T2>::type
type;
150 return divide_round_to_ceiling(
static_cast<type>(numerator),
static_cast<type>(denominator));
161 template <
typename T>
162 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_to_floor(T numerator,
166 const T remainder = numerator % denominator;
167 const T quotient = numerator / denominator;
176 return private_rounded_integral_division::are_same_sign(numerator, denominator) ? quotient : quotient - 1;
188 template <
typename T1,
typename T2>
190 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
191 typename etl::common_type<T1, T2>::type>::type
192 divide_round_to_floor(T1 numerator, T2 denominator) ETL_NOEXCEPT
194 typedef typename etl::common_type<T1, T2>::type
type;
196 return divide_round_to_floor(
static_cast<type>(numerator),
static_cast<type>(denominator));
207 template <
typename T>
208 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_to_floor(T numerator,
212 return numerator / denominator;
224 template <
typename T1,
typename T2>
226 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
227 typename etl::common_type<T1, T2>::type>::type
228 divide_round_to_floor(T1 numerator, T2 denominator) ETL_NOEXCEPT
230 typedef typename etl::common_type<T1, T2>::type
type;
232 const type common_numerator = numerator;
233 const type common_denominator = denominator;
235 return common_numerator / common_denominator;
246 template <
typename T>
247 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_to_infinity(T numerator,
251 const T remainder = numerator % denominator;
252 const T quotient = numerator / denominator;
254 if (private_rounded_integral_division::are_same_sign(numerator, denominator))
257 return (remainder != 0) ? quotient + 1 : quotient;
262 return (remainder != 0) ? quotient - 1 : quotient;
275 template <
typename T1,
typename T2>
277 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
278 typename etl::common_type<T1, T2>::type>::type
279 divide_round_to_infinity(T1 numerator, T2 denominator) ETL_NOEXCEPT
281 typedef typename etl::common_type<T1, T2>::type
type;
283 return divide_round_to_infinity(
static_cast<type>(numerator),
static_cast<type>(denominator));
294 template <
typename T>
295 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type
296 divide_round_to_infinity(T numerator, T denominator) ETL_NOEXCEPT
298 const T remainder = numerator % denominator;
299 const T quotient = numerator / denominator;
301 return remainder ? quotient + 1U : quotient;
313 template <
typename T1,
typename T2>
315 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
316 typename etl::common_type<T1, T2>::type>::type
317 divide_round_to_infinity(T1 numerator, T2 denominator) ETL_NOEXCEPT
319 typedef typename etl::common_type<T1, T2>::type
type;
321 return divide_round_to_infinity(
static_cast<type>(numerator),
static_cast<type>(denominator));
332 template <
typename T>
333 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_to_zero(T numerator,
337 return numerator / denominator;
349 template <
typename T1,
typename T2>
350 ETL_CONSTEXPR14
typename etl::enable_if<etl::is_integral<T1>::value && etl::is_integral<T2>::value,
typename etl::common_type<T1, T2>::type>::type
351 divide_round_to_zero(T1 numerator, T2 denominator) ETL_NOEXCEPT
353 typedef typename etl::common_type<T1, T2>::type
type;
356 const type common_numerator = numerator;
357 const type common_denominator = denominator;
359 return common_numerator / common_denominator;
370 template <
typename T>
371 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_half_up(T numerator,
376 const T remainder = numerator % denominator;
377 const T quotient = numerator / denominator;
380 typedef typename etl::make_unsigned<T>::type utype;
381 utype abs_remainder = remainder < 0 ? utype(0) - utype(remainder) : utype(remainder);
382 utype abs_denominator = denominator < 0 ? utype(0) - utype(denominator) : utype(denominator);
385 utype half_denominator = (abs_denominator + 1) / 2;
387 if (abs_remainder >= half_denominator)
390 if (private_rounded_integral_division::are_same_sign(numerator, denominator))
412 template <
typename T1,
typename T2>
414 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
415 typename etl::common_type<T1, T2>::type>::type
416 divide_round_half_up(T1 numerator, T2 denominator) ETL_NOEXCEPT
418 typedef typename etl::common_type<T1, T2>::type
type;
420 return divide_round_half_up(
static_cast<type>(numerator),
static_cast<type>(denominator));
431 template <
typename T>
432 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_half_up(T numerator,
436 const T remainder = numerator % denominator;
437 const T quotient = numerator / denominator;
440 return (remainder >= (denominator / 2U) + (denominator % 2U)) ? quotient + 1U : quotient;
452 template <
typename T1,
typename T2>
454 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
455 typename etl::common_type<T1, T2>::type>::type
456 divide_round_half_up(T1 numerator, T2 denominator) ETL_NOEXCEPT
458 typedef typename etl::common_type<T1, T2>::type
type;
460 return divide_round_half_up(
static_cast<type>(numerator),
static_cast<type>(denominator));
471 template <
typename T>
472 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_half_down(T numerator,
476 const T quotient = numerator / denominator;
477 const T remainder = numerator % denominator;
479 typedef typename etl::make_unsigned<T>::type utype;
480 const utype abs_denominator = etl::absolute_unsigned(denominator);
481 const utype abs_remainder = etl::absolute_unsigned(remainder);
484 const T direction = private_rounded_integral_division::are_same_sign(numerator, denominator) ? 1 : -1;
488 return abs_remainder > (abs_denominator / 2U) ? quotient + direction : quotient;
500 template <
typename T1,
typename T2>
502 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
503 typename etl::common_type<T1, T2>::type>::type
504 divide_round_half_down(T1 numerator, T2 denominator) ETL_NOEXCEPT
506 typedef typename etl::common_type<T1, T2>::type
type;
508 return divide_round_half_down(
static_cast<type>(numerator),
static_cast<type>(denominator));
519 template <
typename T>
520 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_half_down(T numerator,
524 const T remainder = numerator % denominator;
525 const T quotient = numerator / denominator;
528 return (remainder > (denominator / 2U)) ? quotient + 1U : quotient;
540 template <
typename T1,
typename T2>
542 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
543 typename etl::common_type<T1, T2>::type>::type
544 divide_round_half_down(T1 numerator, T2 denominator) ETL_NOEXCEPT
546 typedef typename etl::common_type<T1, T2>::type
type;
548 return divide_round_half_down(
static_cast<type>(numerator),
static_cast<type>(denominator));
559 template <
typename T>
560 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_half_even(T numerator,
564 const T quotient = numerator / denominator;
565 const T remainder = numerator % denominator;
566 const T direction = ((numerator >= 0) == (denominator >= 0)) ? 1 : -1;
570 typedef typename etl::make_unsigned<T>::type utype;
571 const utype abs_denominator = (denominator < 0) ? (utype(0) - utype(denominator)) : utype(denominator);
572 const utype abs_remainder = (remainder < 0) ? (utype(0) - utype(remainder)) : utype(remainder);
573 const utype half_denominator = abs_denominator / 2U;
576 if ((abs_denominator & 1U) == 0U)
579 if (abs_remainder < half_denominator)
583 else if (abs_remainder > half_denominator)
585 return quotient + direction;
590 return (quotient & 1) == 0 ? quotient : quotient + direction;
596 return (abs_remainder <= half_denominator) ? quotient : (quotient + direction);
609 template <
typename T1,
typename T2>
611 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
612 typename etl::common_type<T1, T2>::type>::type
613 divide_round_half_even(T1 numerator, T2 denominator) ETL_NOEXCEPT
615 typedef typename etl::common_type<T1, T2>::type
type;
617 return divide_round_half_even(
static_cast<type>(numerator),
static_cast<type>(denominator));
628 template <
typename T>
629 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_half_even(T numerator,
633 const T quotient = numerator / denominator;
634 const T remainder = numerator % denominator;
636 if ((remainder * 2U) < denominator)
641 else if ((remainder * 2U) > denominator)
644 return quotient + 1U;
649 return (quotient & 1U) == 0U ? quotient : quotient + 1;
662 template <
typename T1,
typename T2>
664 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
665 typename etl::common_type<T1, T2>::type>::type
666 divide_round_half_even(T1 numerator, T2 denominator) ETL_NOEXCEPT
668 typedef typename etl::common_type<T1, T2>::type
type;
670 return divide_round_half_even(
static_cast<type>(numerator),
static_cast<type>(denominator));
681 template <
typename T>
682 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_signed<T>::value, T>::type divide_round_half_odd(T numerator,
686 const T quotient = numerator / denominator;
687 const T remainder = numerator % denominator;
689 typedef typename etl::make_unsigned<T>::type utype;
690 const utype abs_denominator = etl::absolute_unsigned(denominator);
691 const utype abs_remainder = etl::absolute_unsigned(remainder);
692 const utype half = abs_denominator / 2U;
693 const T direction = private_rounded_integral_division::are_same_sign(numerator, denominator) ? 1 : -1;
696 if ((abs_denominator & 1U) != 0U)
698 return (abs_remainder > half) ? quotient + direction : quotient;
701 if (abs_remainder < half)
705 else if (abs_remainder > half)
707 return quotient + direction;
712 return (quotient & 1) != 0 ? quotient : quotient + direction;
725 template <
typename T1,
typename T2>
727 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_signed<T1>::value && etl::is_signed<T2>::value,
728 typename etl::common_type<T1, T2>::type>::type
729 divide_round_half_odd(T1 numerator, T2 denominator) ETL_NOEXCEPT
731 typedef typename etl::common_type<T1, T2>::type
type;
733 return divide_round_half_odd(
static_cast<type>(numerator),
static_cast<type>(denominator));
744 template <
typename T>
745 ETL_CONSTEXPR14
typename etl::enable_if< etl::is_integral<T>::value && etl::is_unsigned<T>::value, T>::type divide_round_half_odd(T numerator,
749 const T quotient = numerator / denominator;
750 const T remainder = numerator % denominator;
752 if ((remainder * 2U) < denominator)
756 else if ((remainder * 2U) > denominator)
758 return quotient + 1U;
763 return (quotient & 1U) != 0U ? quotient : quotient + 1U;
776 template <
typename T1,
typename T2>
778 typename etl::enable_if< etl::is_integral<T1>::value && etl::is_integral<T2>::value && etl::is_unsigned<T1>::value && etl::is_unsigned<T2>::value,
779 typename etl::common_type<T1, T2>::type>::type
780 divide_round_half_odd(T1 numerator, T2 denominator) ETL_NOEXCEPT
782 typedef typename etl::common_type<T1, T2>::type
type;
784 return divide_round_half_odd(
static_cast<type>(numerator),
static_cast<type>(denominator));