Skip to content

Commit

Permalink
Fix fraction overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Qiuwen-chen committed Jun 19, 2024
1 parent 68076a2 commit 15af3b4
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
37 changes: 34 additions & 3 deletions src/common/repair/utility/Fraction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ void Fraction::reduce()
}
}

int64_t Fraction::limitNumber(int64_t a, int64_t b) const
{
int64_t limit = 1;
a = std::abs(a);
b = std::abs(b);
int64_t max_b = std::numeric_limits<int64_t>::max() / a;
if (max_b < b) {
limit = b / max_b + (b % max_b > 0 ? 1 : 0);
}
return limit;
}

Fraction Fraction::operator+(const Fraction &operand) const
{
int64_t numerator, denominator;
Expand All @@ -72,9 +84,15 @@ Fraction Fraction::operator+(const Fraction &operand) const
denominator = m_denominator;
} else {
int64_t gcd = euclidean(m_denominator, operand.m_denominator);

denominator = m_denominator / gcd;
int64_t limit = limitNumber(denominator, operand.m_denominator);
gcd *= limit;
denominator /= limit;

numerator = (operand.m_denominator / gcd * m_numerator)
+ (m_denominator / gcd * operand.m_numerator);
denominator = m_denominator / gcd * operand.m_denominator;
denominator = denominator * operand.m_denominator;
}
Fraction result(numerator, denominator);
result.reduce();
Expand All @@ -85,8 +103,15 @@ Fraction Fraction::operator*(const Fraction &operand) const
{
int64_t gcd1 = euclidean(m_numerator, operand.m_denominator);
int64_t gcd2 = euclidean(operand.m_numerator, m_denominator);

int64_t denominator1 = m_denominator / gcd2;
int64_t denominator2 = operand.m_denominator / gcd1;
int64_t limit = limitNumber(denominator1, denominator2);
gcd2 *= limit;
denominator1 /= limit;

Fraction result(m_numerator / gcd1 * (operand.m_numerator / gcd2),
m_denominator / gcd2 * (operand.m_denominator / gcd1));
denominator1 * denominator2);
return result;
}

Expand All @@ -96,9 +121,15 @@ Fraction &Fraction::operator+=(const Fraction &operand)
m_numerator += operand.m_numerator;
} else {
int64_t gcd = euclidean(m_denominator, operand.m_denominator);

int64_t denominator = operand.m_denominator / gcd;
int64_t limit = limitNumber(m_denominator, denominator);
gcd *= limit;
denominator /= limit;

m_numerator = (operand.m_denominator / gcd * m_numerator)
+ (m_denominator / gcd * operand.m_numerator);
m_denominator *= operand.m_denominator / gcd;
m_denominator *= denominator;
}
reduce();
return *this;
Expand Down
1 change: 1 addition & 0 deletions src/common/repair/utility/Fraction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Fraction final {
protected:
void reduce();
int64_t euclidean(int64_t a, int64_t b) const;
int64_t limitNumber(int64_t a, int64_t b) const;

private:
int64_t m_numerator;
Expand Down

0 comments on commit 15af3b4

Please sign in to comment.