Fraction type documentation
Syntax highlighting is disabled until I can figure out how to comply with GDPR (it is external content after all). The source still has it enabled and the relevant lines are commented out on this page (you could uncomment them with Dev Tools, but that's none of my responsibility...)Basics
Basic UsageTop
Here's a basic program demonstrating the easy use of the Fraction class. Assume you'd like to write the mathematical function
double f(int x)
But what about things like
double f(double x)
But then you'd have the topic of floating-point accuracy which means your code will get inaccurate with large numbers. So, how do we solve this? With the
#include <cstdio>
#include "npasson_fraction.hpp"
using npasson::Fraction;
Fraction f(Fraction x) {
return 1/x;
}
double d(double x) {
return 1/x;
}
int main() {
// for f(x)=1/x, it needs to hold that x == f(f(x)) == f(f(f(f(x)))) and so on.
Fraction a = 1'000'000'000'000'000;
double b = 1'000'000'000'000'000;
if (a == f(f(a))) printf("Fraction Test 1 holds\n");
if (a == f(f(f(f(a))))) printf("Fraction Test 2 holds\n");
if (a == f(f(f(f(f(f(a))))))) printf("Fraction Test 3 holds\n");
if (a == d(d(b))) printf("Double Test 1 holds\n");
if (a == d(d(d(d(b))))) printf("Double Test 2 holds\n");
if (a == d(d(d(d(d(d(b))))))) printf("Double Test 3 holds\n");
}
Compiled with
g++ -std=c++17 -Wall -O0
the program outputs
Fraction Test 1 holds
Fraction Test 2 holds
Fraction Test 3 holds
Process finished with exit code 0
As demonstrated in the example, you can treat Fraction like a normal numeric type. You can initialize it in many different ways, see Constructors, and also use it in most calculations, see Operators.
Supported typesTop
The following types are completely supported in all operations with Fractions:signed short signed int signed long int signed long long int unsigned short unsigned int unsigned long int unsigned long long int float double
long double
ConstructorsTop
The following constructors exist:
Fraction()
Fraction(Fraction)
Fraction(long long signed int, long long signed int);
Fraction(short)
Fraction(unsigned short)
Fraction(int)
Fraction(unsigned int)
Fraction(long int)
Fraction(unsigned long int)
Fraction(long long int)
Fraction(unsigned long long int)
Fraction(float)
Fraction(double)
Fraction(long double)
Fraction(bool)
Implicit constructors
Implicit construction is allowed for the following types:- signed int
- signed long long int
- double
Fraction a = 5;
Fraction b = 78236487263874622ll;
Fraction c = 3.7;
These types can also be used in place of Fraction types, as implicit conversion will take care of them.
(Mathematical) fraction constructor
Fraction(long long signed int, long long signed int);
is the fraction constructor. It is used like Explicit constructors
For all other types, an explicit constructor is required.
Fraction a(26.3f); // float
Fraction b("1.3"); // std::string
Fraction c(a); // Fraction
Fraction d("2,5"); // std::string with European decimal place
const char* temp = "3.7";
Fraction f(temp); // const char*
Bool constructor
The bool constructor works as following. Given a true, it is functionally equivalent to an empty constructor:
Fraction(true) == Fraction()
Given a false, it constructs a Fraction where the Fraction::_invalid bit is triggered. This bit indicates an invalid Fraction. Invalid fractions have undefined behavior on all operations. Validity can and should be checked via
Fraction f(false);
if (f.valid()) {
// will not execute
}
There also exists the macro DestructorsTop
There exists only one destructor:
~Fraction() = default;
Operations
Every operator listed here can either be used between two Fractions, or a Fraction and a type listed in the Supported types list.Arithmetic operatorsTop
The following arithmetic operators exist:+ Addition- Subtraction* Multiplication/ Division+= Addition-assignment-= Subtraction-assignment*= Multiplication-assignment/= Division-assignment
+ ,- ,* and/ always return aFraction .+= ,-= ,*= and/= return a Fraction when the first argument is a Fraction. Otherwise, when the first argument isT , they returnT .
Comparison operatorsTop
The following comparison operators exist:== Equals!= Not Equals< Smaller than> Larger than<= Smaller or equal>= Larger or equal
Unary operatorsTop
Assumingf++ Post-Increment++f Pre-Incrementf-- Post-Decrement--f Pre-Decrement-f Additive Inverse+f Plus Operator
The unary
The rest of the operators do what you'd expect, that means
CastsTop
You can cast to all supported types and to- The casts to all integer types are truncating casts, this means 3.75 would become 3.
- The cast to bool is the same as
f != 0 . - Currently, the cast is implemented as a simple division. There is no overflow check.
Fraction f = 3.75;
int i = (int)f;
// i is now 3
Functions
is_supported_type() Top
template <typename T> static constexpr bool npasson::Fraction::is_supported_type()
Example usage:
if(Fraction::is_arithmetic_type<float>()) {
// do something
}
Returns valid() Top
bool npasson::Fraction::valid() const
Example usage:
Fraction f = 3;
f /= 0;
if(f.valid()) {
// does not execute, f has been divided by zero and is not valid anymore
}
Returns false if the Fraction is invalid. In that case, all operations made on the Fraction are undefined behavior. This can happen in three cases:
- The Fraction has been subjected to an invalid operation, such as dividing by zero.
- The Fraction has been initialized with a
std::string /char* which does not represent a number. - The Fraction has been initialized via
Fraction(false) .
str() Top
std::string npasson::Fraction::str()
Returns a decimal Example usage:
Fraction f = 25;
std::string str = "I am " + f.str() + " years old!";
c_str() Top
const char* npasson::Fraction::c_str()
Returns a decimal Example usage:
Fraction f = 25;
printf("I am %s years old!", f.c_str());
f_str() Top
std::string npasson::Fraction::f_str()
Returns a fraction Example usage:
Fraction f = 3.75;
std::string str = f.str() " in fraction form is " + f.f_str();
std::cout << str << std::endl;
This will output:
3.75 in fraction form is 15/4
invert() Top
npasson::Fraction npasson::Fraction::invert() const
Returns an inverted fraction.
invert(Fraction) Top
static void npasson::Fraction::invert(Fraction&)
Inverts the given Fraction.
pow(int) Top
npasson::Fraction npasson::Fraction::pow(int)
abs(T) Top
template <typename T> npasson::abs(T t)
Returns the absolute value of the type. The type needs to support Debugging
To enable debugging functions, you need totest(T,U) Top
template <typename T, typename U> npasson::Fraction::test(T& a, U& b)
Prints the complete list of operators available to the Fraction class and the results between the two types. Results are cast to double after operation to ensure displayability. This can be used to find bugs in operators.
Example usage:
float one = 16;
npasson::Fraction two = 3.5;
npasson::Fraction::test(one, two);
This prints:
==========================
| Operator test run |
==========================
| a is 16 of type float
| b is 3.5 of type npasson::Fraction
| a+b is 19.5 of type npasson::Fraction
| b+a is 19.5 of type npasson::Fraction
| a-b is 12.5 of type npasson::Fraction
| b-a is -12.5 of type npasson::Fraction
| a*b is 56 of type npasson::Fraction
| b*a is 56 of type npasson::Fraction
| a/b is 4.57143 of type npasson::Fraction
| b/a is 0.21875 of type npasson::Fraction
==========================
| (operators are reset before
| each following operation)
--------------------------
| a+=b is 19.5 of type float
| a is now 19.5
| b is now 3.5
---------=RESET=----------
| a is now 16
| b is now 3.5
| b+=a is 19.5 of type npasson::Fraction
| a is now 16
| b is now 19.5
---------=RESET=----------
| a is now 16
| b is now 3.5
| a-=b is 12.5 of type float
| a is now 12.5
| b is now 3.5
---------=RESET=----------
| a is now 16
| b is now 3.5
| b-=a is -12.5 of type npasson::Fraction
| a is now 16
| b is now -12.5
---------=RESET=----------
| a is now 16
| b is now 3.5
| a*=b is 56 of type float
| a is now 56
| b is now 3.5
---------=RESET=----------
| a is now 16
| b is now 3.5
| b*=a is 56 of type npasson::Fraction
| a is now 16
| b is now 56
---------=RESET=----------
| a is now 16
| b is now 3.5
| a/=b is 4.57143 of type float
| a is now 4.57143
| b is now 3.5
---------=RESET=----------
| a is now 16
| b is now 3.5
| b/=a is 0.21875 of type npasson::Fraction
| a is now 16
| b is now 0.21875
---------=RESET=----------
| a is now 16
| b is now 3.5
==========================
| Comparison
| a is 16
| b is 3.5
| a<b is false
| a>b is true
| a<=b is false
| a>=b is true
| a==b is false
| a!=b is true
==========================
Experimental compileTop
#define NPASSON_EXPERIMENTAL_COMPILE
Add this line before including the header. This will include the Syntax highlighting by highlight.js using the