1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef UTIL_SIMPLE_FRACTION_H_ 6*3f982cf4SFabien Sanglard #define UTIL_SIMPLE_FRACTION_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <cmath> 9*3f982cf4SFabien Sanglard #include <limits> 10*3f982cf4SFabien Sanglard #include <string> 11*3f982cf4SFabien Sanglard 12*3f982cf4SFabien Sanglard #include "absl/strings/string_view.h" 13*3f982cf4SFabien Sanglard #include "platform/base/error.h" 14*3f982cf4SFabien Sanglard 15*3f982cf4SFabien Sanglard namespace openscreen { 16*3f982cf4SFabien Sanglard 17*3f982cf4SFabien Sanglard // SimpleFraction is used to represent simple (or "common") fractions, composed 18*3f982cf4SFabien Sanglard // of a rational number written a/b where a and b are both integers. 19*3f982cf4SFabien Sanglard // Some helpful notes on SimpleFraction assumptions/limitations: 20*3f982cf4SFabien Sanglard // 1. SimpleFraction does not perform reductions. 2/4 != 1/2, and -1/-1 != 1/1. 21*3f982cf4SFabien Sanglard // 2. denominator = 0 is considered undefined. 22*3f982cf4SFabien Sanglard // 3. numerator = saturates range to int min or int max 23*3f982cf4SFabien Sanglard // 4. A SimpleFraction is "positive" if and only if it is defined and at least 24*3f982cf4SFabien Sanglard // equal to zero. Since reductions are not performed, -1/-1 is negative. 25*3f982cf4SFabien Sanglard class SimpleFraction { 26*3f982cf4SFabien Sanglard public: 27*3f982cf4SFabien Sanglard static ErrorOr<SimpleFraction> FromString(absl::string_view value); 28*3f982cf4SFabien Sanglard std::string ToString() const; 29*3f982cf4SFabien Sanglard 30*3f982cf4SFabien Sanglard constexpr SimpleFraction() = default; SimpleFraction(int numerator)31*3f982cf4SFabien Sanglard constexpr SimpleFraction(int numerator) // NOLINT 32*3f982cf4SFabien Sanglard : numerator_(numerator) {} SimpleFraction(int numerator,int denominator)33*3f982cf4SFabien Sanglard constexpr SimpleFraction(int numerator, int denominator) 34*3f982cf4SFabien Sanglard : numerator_(numerator), denominator_(denominator) {} 35*3f982cf4SFabien Sanglard 36*3f982cf4SFabien Sanglard constexpr SimpleFraction(const SimpleFraction&) = default; 37*3f982cf4SFabien Sanglard constexpr SimpleFraction(SimpleFraction&&) noexcept = default; 38*3f982cf4SFabien Sanglard constexpr SimpleFraction& operator=(const SimpleFraction&) = default; 39*3f982cf4SFabien Sanglard constexpr SimpleFraction& operator=(SimpleFraction&&) = default; 40*3f982cf4SFabien Sanglard ~SimpleFraction() = default; 41*3f982cf4SFabien Sanglard 42*3f982cf4SFabien Sanglard constexpr bool operator==(const SimpleFraction& other) const { 43*3f982cf4SFabien Sanglard return numerator_ == other.numerator_ && denominator_ == other.denominator_; 44*3f982cf4SFabien Sanglard } 45*3f982cf4SFabien Sanglard 46*3f982cf4SFabien Sanglard constexpr bool operator!=(const SimpleFraction& other) const { 47*3f982cf4SFabien Sanglard return !(*this == other); 48*3f982cf4SFabien Sanglard } 49*3f982cf4SFabien Sanglard is_defined()50*3f982cf4SFabien Sanglard constexpr bool is_defined() const { return denominator_ != 0; } 51*3f982cf4SFabien Sanglard is_positive()52*3f982cf4SFabien Sanglard constexpr bool is_positive() const { 53*3f982cf4SFabien Sanglard return (numerator_ >= 0) && (denominator_ > 0); 54*3f982cf4SFabien Sanglard } 55*3f982cf4SFabien Sanglard 56*3f982cf4SFabien Sanglard constexpr explicit operator double() const { 57*3f982cf4SFabien Sanglard if (denominator_ == 0) { 58*3f982cf4SFabien Sanglard return nan(""); 59*3f982cf4SFabien Sanglard } 60*3f982cf4SFabien Sanglard return static_cast<double>(numerator_) / static_cast<double>(denominator_); 61*3f982cf4SFabien Sanglard } 62*3f982cf4SFabien Sanglard numerator()63*3f982cf4SFabien Sanglard constexpr int numerator() const { return numerator_; } denominator()64*3f982cf4SFabien Sanglard constexpr int denominator() const { return denominator_; } 65*3f982cf4SFabien Sanglard 66*3f982cf4SFabien Sanglard private: 67*3f982cf4SFabien Sanglard int numerator_ = 0; 68*3f982cf4SFabien Sanglard int denominator_ = 1; 69*3f982cf4SFabien Sanglard }; 70*3f982cf4SFabien Sanglard 71*3f982cf4SFabien Sanglard } // namespace openscreen 72*3f982cf4SFabien Sanglard 73*3f982cf4SFabien Sanglard #endif // UTIL_SIMPLE_FRACTION_H_ 74