xref: /aosp_15_r20/external/openscreen/util/simple_fraction.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
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