MLIR 22.0.0git
Fraction.h
Go to the documentation of this file.
1//===- Fraction.h - MLIR Fraction Class -------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This is a simple class to represent fractions. It supports arithmetic,
10// comparison, floor, and ceiling operations.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_ANALYSIS_PRESBURGER_FRACTION_H
15#define MLIR_ANALYSIS_PRESBURGER_FRACTION_H
16
17#include "llvm/ADT/DynamicAPInt.h"
18#include "llvm/Support/raw_ostream.h"
19
20namespace mlir {
21namespace presburger {
22using llvm::DynamicAPInt;
23
24/// A class to represent fractions. The sign of the fraction is represented
25/// in the sign of the numerator; the denominator is always positive.
26///
27/// Note that overflows may occur if the numerator or denominator are not
28/// representable by 64-bit integers.
29struct Fraction {
30 /// Default constructor initializes the represented rational number to zero.
31 Fraction() = default;
32
33 /// Construct a Fraction from a numerator and denominator.
34 Fraction(const DynamicAPInt &oNum, const DynamicAPInt &oDen = DynamicAPInt(1))
35 : num(oNum), den(oDen) {
36 if (den < 0) {
37 num = -num;
38 den = -den;
39 }
40 }
41 /// Overloads for passing literals.
42 Fraction(const DynamicAPInt &num, int64_t den)
43 : Fraction(num, DynamicAPInt(den)) {}
44 Fraction(int64_t num, const DynamicAPInt &den = DynamicAPInt(1))
45 : Fraction(DynamicAPInt(num), den) {}
47 : Fraction(DynamicAPInt(num), DynamicAPInt(den)) {}
48
49 // Return the value of the fraction as an integer. This should only be called
50 // when the fraction's value is really an integer.
51 DynamicAPInt getAsInteger() const {
52 assert(num % den == 0 && "Get as integer called on non-integral fraction!");
53 return num / den;
54 }
55
56 llvm::raw_ostream &print(llvm::raw_ostream &os) const {
57 return os << "(" << num << "/" << den << ")";
58 }
59
60 /// The numerator and denominator, respectively. The denominator is always
61 /// positive.
62 DynamicAPInt num{0}, den{1};
63};
64
65/// Three-way comparison between two fractions.
66/// Returns +1, 0, and -1 if the first fraction is greater than, equal to, or
67/// less than the second fraction, respectively.
68inline int compare(const Fraction &x, const Fraction &y) {
69 DynamicAPInt diff = x.num * y.den - y.num * x.den;
70 if (diff > 0)
71 return +1;
72 if (diff < 0)
73 return -1;
74 return 0;
75}
76
77inline DynamicAPInt floor(const Fraction &f) { return floorDiv(f.num, f.den); }
78
79inline DynamicAPInt ceil(const Fraction &f) { return ceilDiv(f.num, f.den); }
80
81inline Fraction operator-(const Fraction &x) { return Fraction(-x.num, x.den); }
82
83inline bool operator<(const Fraction &x, const Fraction &y) {
84 return compare(x, y) < 0;
85}
86
87inline bool operator<=(const Fraction &x, const Fraction &y) {
88 return compare(x, y) <= 0;
89}
90
91inline bool operator==(const Fraction &x, const Fraction &y) {
92 return compare(x, y) == 0;
93}
94
95inline bool operator!=(const Fraction &x, const Fraction &y) {
96 return compare(x, y) != 0;
97}
98
99inline bool operator>(const Fraction &x, const Fraction &y) {
100 return compare(x, y) > 0;
101}
102
103inline bool operator>=(const Fraction &x, const Fraction &y) {
104 return compare(x, y) >= 0;
105}
106
107inline Fraction abs(const Fraction &f) {
108 assert(f.den > 0 && "denominator of fraction must be positive!");
109 return Fraction(abs(f.num), f.den);
110}
111
112inline Fraction reduce(const Fraction &f) {
113 if (f == Fraction(0))
114 return Fraction(0, 1);
115 DynamicAPInt g = gcd(abs(f.num), abs(f.den));
116 return Fraction(f.num / g, f.den / g);
117}
118
119inline Fraction operator*(const Fraction &x, const Fraction &y) {
120 return reduce(Fraction(x.num * y.num, x.den * y.den));
121}
122
123inline Fraction operator/(const Fraction &x, const Fraction &y) {
124 return reduce(Fraction(x.num * y.den, x.den * y.num));
125}
126
127inline Fraction operator+(const Fraction &x, const Fraction &y) {
128 return reduce(Fraction(x.num * y.den + x.den * y.num, x.den * y.den));
129}
130
131inline Fraction operator-(const Fraction &x, const Fraction &y) {
132 return reduce(Fraction(x.num * y.den - x.den * y.num, x.den * y.den));
133}
134
135// Find the integer nearest to a given fraction.
136inline DynamicAPInt round(const Fraction &f) {
137 DynamicAPInt rem = f.num % f.den;
138 return (f.num / f.den) + (rem > f.den / 2);
139}
140
141inline Fraction &operator+=(Fraction &x, const Fraction &y) {
142 x = x + y;
143 return x;
144}
145
146inline Fraction &operator-=(Fraction &x, const Fraction &y) {
147 x = x - y;
148 return x;
149}
150
151inline Fraction &operator/=(Fraction &x, const Fraction &y) {
152 x = x / y;
153 return x;
154}
155
156inline Fraction &operator*=(Fraction &x, const Fraction &y) {
157 x = x * y;
158 return x;
159}
160
161inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Fraction &x) {
162 x.print(os);
163 return os;
164}
165
166} // namespace presburger
167} // namespace mlir
168
169#endif // MLIR_ANALYSIS_PRESBURGER_FRACTION_H
#define rem(a, b)
Fraction & operator-=(Fraction &x, const Fraction &y)
Definition Fraction.h:146
Fraction operator+(const Fraction &x, const Fraction &y)
Definition Fraction.h:127
bool operator==(const Fraction &x, const Fraction &y)
Definition Fraction.h:91
bool operator>(const Fraction &x, const Fraction &y)
Definition Fraction.h:99
bool operator<(const Fraction &x, const Fraction &y)
Definition Fraction.h:83
int compare(const Fraction &x, const Fraction &y)
Three-way comparison between two fractions.
Definition Fraction.h:68
DynamicAPInt floor(const Fraction &f)
Definition Fraction.h:77
bool operator>=(const Fraction &x, const Fraction &y)
Definition Fraction.h:103
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const Fraction &x)
Definition Fraction.h:161
DynamicAPInt ceil(const Fraction &f)
Definition Fraction.h:79
Fraction reduce(const Fraction &f)
Definition Fraction.h:112
Fraction operator-(const Fraction &x)
Definition Fraction.h:81
bool operator<=(const Fraction &x, const Fraction &y)
Definition Fraction.h:87
DynamicAPInt round(const Fraction &f)
Definition Fraction.h:136
Fraction abs(const Fraction &f)
Definition Fraction.h:107
bool operator!=(const Fraction &x, const Fraction &y)
Definition Fraction.h:95
Fraction & operator/=(Fraction &x, const Fraction &y)
Definition Fraction.h:151
Fraction & operator*=(Fraction &x, const Fraction &y)
Definition Fraction.h:156
Fraction operator*(const Fraction &x, const Fraction &y)
Definition Fraction.h:119
Fraction & operator+=(Fraction &x, const Fraction &y)
Definition Fraction.h:141
Fraction operator/(const Fraction &x, const Fraction &y)
Definition Fraction.h:123
Include the generated interface declarations.
A class to represent fractions.
Definition Fraction.h:29
Fraction()=default
Default constructor initializes the represented rational number to zero.
Fraction(int64_t num, const DynamicAPInt &den=DynamicAPInt(1))
Definition Fraction.h:44
Fraction(const DynamicAPInt &oNum, const DynamicAPInt &oDen=DynamicAPInt(1))
Construct a Fraction from a numerator and denominator.
Definition Fraction.h:34
DynamicAPInt getAsInteger() const
Definition Fraction.h:51
llvm::raw_ostream & print(llvm::raw_ostream &os) const
Definition Fraction.h:56
Fraction(const DynamicAPInt &num, int64_t den)
Overloads for passing literals.
Definition Fraction.h:42
Fraction(int64_t num, int64_t den)
Definition Fraction.h:46
DynamicAPInt num
The numerator and denominator, respectively.
Definition Fraction.h:62