diff --git a/libgnucash/engine/gnc-rational-rounding.hpp b/libgnucash/engine/gnc-rational-rounding.hpp index f5cdb50310..692301701e 100644 --- a/libgnucash/engine/gnc-rational-rounding.hpp +++ b/libgnucash/engine/gnc-rational-rounding.hpp @@ -23,6 +23,7 @@ #ifndef __GNC_RATIONAL_ROUNDING_HPP__ #define __GNC_RATIONAL_ROUNDING_HPP__ #include "gnc-numeric.h" +#include "gnc-int128.hpp" enum class RoundType { @@ -105,7 +106,18 @@ round(T num, T den, T rem, RT2T) { if (rem == 0) return num; - if (rem * 2 > den) + if (std::abs(rem * 2) > std::abs(den)) + return num + (num < 0 ? -1 : 1); + return num; +} + +template <> inline GncInt128 +round(GncInt128 num, GncInt128 den, GncInt128 rem, + RT2T) +{ + if (rem == 0) + return num; + if (rem.abs() * 2 > den.abs()) return num + (num < 0 ? -1 : 1); return num; } @@ -115,7 +127,18 @@ round(T num, T den, T rem, RT2T) { if (rem == 0) return num; - if (rem * 2 >= den) + if (std::abs(rem) * 2 >= std::abs(den)) + return num + (num < 0 ? -1 : 1); + return num; +} + +template <> inline GncInt128 +round(GncInt128 num, GncInt128 den, GncInt128 rem, + RT2T) +{ + if (rem == 0) + return num; + if (rem.abs() * 2 >= den.abs()) return num + (num < 0 ? -1 : 1); return num; } @@ -125,9 +148,21 @@ round(T num, T den, T rem, RT2T) { if (rem == 0) return num; - if (rem * 2 > den || (rem * 2 == den && num % 2)) + if (std::abs(rem * 2) > std::abs(den) || + (std::abs(rem * 2) == std::abs(den) && num % 2)) return num += (num < 0 ? -1 : 1); return num; } +template<> inline GncInt128 +round(GncInt128 num, GncInt128 den, GncInt128 rem, + RT2T) +{ + if (rem == 0) + return num; + if (rem.abs() * 2 > den.abs() || + (rem.abs() * 2 == den.abs() && num % 2)) + return num += (num < 0 ? -1 : 1); + return num; +} #endif //__GNC_RATIONAL_ROUNDING_HPP__