blob: 57dc3705f378cd248facdccf74f1810f35fc8f26 [file] [log] [blame] [edit]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/impeller/geometry/rational.h"
#include <cmath>
#include <cstdlib>
#include <numeric>
namespace impeller {
namespace {
uint32_t AbsToUnsigned(int32_t x) {
return static_cast<uint32_t>(std::abs(x));
}
} // namespace
bool Rational::operator==(const Rational& that) const {
if (den_ == that.den_) {
return num_ == that.num_;
} else if ((num_ >= 0) != (that.num_ >= 0)) {
return false;
} else {
return AbsToUnsigned(num_) * that.den_ == AbsToUnsigned(that.num_) * den_;
}
}
bool Rational::operator!=(const Rational& that) const {
return !(*this == that);
}
bool Rational::operator<(const Rational& that) const {
if (den_ == that.den_) {
return num_ < that.num_;
} else if ((num_ >= 0) != (that.num_ >= 0)) {
return num_ < that.num_;
} else {
return AbsToUnsigned(num_) * that.den_ < AbsToUnsigned(that.num_) * den_;
}
}
uint64_t Rational::GetHash() const {
if (num_ == 0) {
return 0;
}
uint64_t gcd = std::gcd(num_, den_);
return ((num_ / gcd) << 32) | (den_ / gcd);
}
Rational Rational::Invert() const {
if (num_ >= 0) {
return Rational(den_, num_);
} else {
return Rational(-1 * static_cast<int32_t>(den_), std::abs(num_));
}
}
} // namespace impeller