Arithmetic/Rational: Difference between revisions

m
(minor fix)
m (→‎{{header|Wren}}: Minor tidy)
 
(7 intermediate revisions by 4 users not shown)
Line 19:
 
 
;Related tasktasks:
*   [[Perfect Numbers]]
*   [[Check Machin-like formulas]]
<br><br>
 
Line 558 ⟶ 559:
return 0;
}</syntaxhighlight>
 
===Without using external libraries===
<syntaxhighlight lang="c++">
#include <cmath>
#include <cstdint>
#include <iostream>
#include <numeric>
#include <stdexcept>
 
class Rational {
public:
/// Constructors ///
Rational() : numer(0), denom(1) {}
 
Rational(const int64_t number) : numer(number), denom(1) {}
 
Rational(const int64_t& numerator, const int64_t& denominator) : numer(numerator), denom(denominator) {
if ( numer == 0 ) {
denom = 1;
} else if ( denom == 0 ) {
throw std::invalid_argument("Denominator cannot be zero: " + denom);
} else if ( denom < 0 ) {
numer = -numer;
denom = -denom;
}
 
int64_t divisor = std::gcd(numerator, denom);
numer = numer / divisor;
denom = denom / divisor;
}
 
Rational(const Rational& other) : numer(other.numer), denom(other.denom) {}
 
/// Operators ///
Rational& operator=(const Rational& other) {
if ( *this != other ) { numer = other.numer; denom = other.denom; }
return *this;
}
 
bool operator!=(const Rational& other) const { return ! ( *this == other ); }
 
bool operator==(const Rational& other) const {
if ( numer == other.numer && denom == other.denom ) { return true; }
return false;
}
 
Rational& operator+=(const Rational& other) {
*this = Rational(numer* other.denom + other.numer * denom, denom * other.denom);
return *this;
}
 
Rational operator+(const Rational& other) const { return Rational(*this) += other; }
 
Rational& operator-=(const Rational& other) {
Rational temp(other);
temp.numer = -temp.numer;
return *this += temp;
}
Rational operator-(const Rational& other) const { return Rational(*this) -= other; }
 
Rational& operator*=(const Rational& other) {
*this = Rational(numer * other.numer, denom * other.denom);
return *this;
}
Rational operator*(const Rational& other) const { return Rational(*this) *= other; };
 
Rational& operator/=(const Rational other) {
Rational temp(other.denom, other.numer);
*this *= temp;
return *this;
}
 
Rational operator/(const Rational& other) const { return Rational(*this) /= other; };
 
bool operator<(const Rational& other) const { return numer * other.denom < denom * other.numer; }
 
bool operator<=(const Rational& other) const { return ! ( other < *this ); }
 
bool operator>(const Rational& other) const { return other < *this; }
 
bool operator>=(const Rational& other) const { return ! ( *this < other ); }
 
Rational operator-() const { return Rational(-numer, denom); }
 
Rational& operator++() { numer += denom; return *this; }
 
Rational operator++(int) { Rational temp = *this; ++*this; return temp; }
 
Rational& operator--() { numer -= denom; return *this; }
 
Rational operator--(int) { Rational temp = *this; --*this; return temp; }
 
friend std::ostream& operator<<(std::ostream& outStream, const Rational& other) {
outStream << other.numer << "/" << other.denom;
return outStream;
}
 
/// Methods ///
Rational reciprocal() const { return Rational(denom, numer); }
 
Rational positive() const { return Rational(abs(numer), denom); }
 
int64_t to_integer() const { return numer / denom; }
 
double to_double() const { return (double) numer / denom; }
 
int64_t hash() const { return std::hash<int64_t>{}(numer) ^ std::hash<int64_t>{}(denom); }
private:
int64_t numer;
int64_t denom;
};
 
int main() {
std::cout << "Perfect numbers less than 2^19:" << std::endl;
const int32_t limit = 1 << 19;
for ( int32_t candidate = 2; candidate < limit; ++candidate ) {
Rational sum = Rational(1, candidate);
int32_t square_root = (int32_t) sqrt(candidate);
for ( int32_t factor = 2; factor <= square_root; ++factor ) {
if ( candidate % factor == 0 ) {
sum += Rational(1, factor);
sum += Rational(1, candidate / factor);
}
}
 
if ( sum == Rational(1) ) {
std::cout << candidate << std::endl;
}
}
}
</syntaxhighlight>
{{ out }}
<pre>
Perfect numbers less than 2^19:
6
28
496
8128
</pre>
 
=={{header|Clojure}}==
Line 3,000 ⟶ 3,142:
}
class:
Module Rational (.numerator, .denominator) {
if .denominator<=0 then Error "Positive onlyZero denominator"
gcd1=lambda (a as decimal, b as decimalsgn=Sgn(.numerator)*Sgn(.denominator) -> {
if a.denominator<b then swap a,b=abs(.denominator)
g.numerator<=a mod babs(.numerator)*sgn
whilegcd1=lambda g(a as decimal, b as decimal) -> {
if a=<b:b=g: g=athen modswap a,b
g=a mod b
while g {
a=b:b=g: g=a mod b
}
=abs(b)
}
gdcval=gcd1(abs(.numerator), .denominator)
if gdcval<.denominator and gdcval<>0 then
.denominator/=gdcval
.numerator/=gdcval
end if
.gcd<=gcd1
.lcm<=lambda gcd=gcd1 (a as decimal, b as decimal) -> {
=a/gcd(a,b)*b
}
=abs(b)
}
.gcd<=gcd1
.lcm<=lambda gcd=gcd1 (a as decimal, b as decimal) -> {
=a/gcd(a,b)*b
}
}
}
sum=rational(1, 1)
Line 3,312 ⟶ 3,462:
 
=={{header|Objective-C}}==
See [[Arithmetic/Rational/Objective-C]].
<div style="text-align:right;font-size:7pt">''<nowiki>[</nowiki>This section is included from [[Arithmetic/Rational/Objective-C|a subpage]] and should be edited there, not here.<nowiki>]</nowiki>''</div>
{{:Arithmetic/Rational/Objective-C}}
 
=={{header|OCaml}}==
Line 4,979 ⟶ 5,128:
{{libheader|Wren-rat}}
The latter module already contains support for rational number arithmetic.
<syntaxhighlight lang="ecmascriptwren">import "./math" for Int
import "./rat" for Rat
 
System.print("The following numbers (less than 2^19) are perfect:")
9,476

edits