Arithmetic/Rational: Difference between revisions

m
m (syntax highlighting fixup automation)
m (→‎{{header|Wren}}: Minor tidy)
 
(12 intermediate revisions by 8 users not shown)
Line 1:
{{task|Arithmetic operations}}
[[Category:Arithmetic]]
{{task|Arithmetic operations}}
 
;Task:
Line 19:
 
 
;Related tasktasks:
*   [[Perfect Numbers]]
*   [[Check Machin-like formulas]]
<br><br>
 
Line 26 ⟶ 27:
Calculations on a real Atari 8-bit computer take quite long time. It is recommended to use an emulator capable with increasing speed of Atari CPU.
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang=Action"action!">INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
TYPE Frac=[INT num,den]
Line 199 ⟶ 200:
{{works with|ALGOL 68|Standard - no extensions to language used}}
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
<syntaxhighlight lang="algol68"> MODE FRAC = STRUCT( INT num #erator#, den #ominator#);
FORMAT frac repr = $g(-0)"//"g(-0)$;
Line 347 ⟶ 348:
Arturo comes with built-in support for rational numbers.
 
<syntaxhighlight lang="rebol">a: to :rational [1 2]
b: to :rational [3 4]
 
Line 372 ⟶ 373:
a - b : -1/4
a * b : 3/8
a / b : 02/3
a // b : 2/3
a % b : 1/2
Line 381 ⟶ 382:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> *FLOAT64
DIM frac{num, den}
DIM Sum{} = frac{}, Kf{} = frac{}, One{} = frac{}
Line 453 ⟶ 454:
=={{header|C}}==
C does not have overloadable operators. The following implementation <u>''does not define all operations''</u> so as to keep the example short. Note that the code passes around struct values instead of pointers to keep it simple, a practice normally avoided for efficiency reasons.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#define FMT "%lld"
Line 531 ⟶ 532:
{{libheader|Boost}}
Boost provides a rational number template.
<syntaxhighlight lang="cpp">#include <iostream>
#include "math.h"
#include "boost/rational.hpp"
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}}==
Ratios are built in to Clojure and support math operations already. They automatically reduce and become Integers if possible.
<syntaxhighlight lang=Clojure"clojure">user> 22/7
22/7
user> 34/2
Line 570 ⟶ 712:
=={{header|Common Lisp}}==
Common Lisp has rational numbers built-in and integrated with all other number types. Common Lisp's number system is not extensible so reimplementing rational arithmetic would require all-new operator names.
<syntaxhighlight lang="lisp">(loop for candidate from 2 below (expt 2 19)
for sum = (+ (/ candidate)
(loop for factor from 2 to (isqrt candidate)
Line 579 ⟶ 721:
 
=={{header|D}}==
<syntaxhighlight lang="d">import std.bigint, std.traits, std.conv;
 
// std.numeric.gcd doesn't work with BigInt.
Line 779 ⟶ 921:
{{libheader| Boost.Rational}}[[https://github.com/MaiconSoft/DelphiBoostLib]]
{{Trans|C#}}
<syntaxhighlight lang=Delphi"delphi">
program Arithmetic_Rational;
 
Line 818 ⟶ 960:
=={{header|EchoLisp}}==
EchoLisp supports rational numbers as native type. "Big" rational i.e bigint/bigint are not supported.
<syntaxhighlight lang="lisp">
;; Finding perfect numbers
(define (sum/inv n) ;; look for div's in [2..sqrt(n)] and add 1/n
Line 827 ⟶ 969:
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="lisp">
;; rational operations
(+ 1/42 1/666) → 59/2331
Line 848 ⟶ 990:
 
=={{header|Elisa}}==
<syntaxhighlight lang=Elisa"elisa">component RationalNumbers;
type Rational;
Rational(Numerator = integer, Denominater = integer) -> Rational;
Line 910 ⟶ 1,052:
end component RationalNumbers;</syntaxhighlight>
Tests
<syntaxhighlight lang=Elisa"elisa">use RationalNumbers;
 
PerfectNumbers( Limit = integer) -> multi(integer);
Line 933 ⟶ 1,075:
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Rational do
import Kernel, except: [div: 2]
Line 1,014 ⟶ 1,156:
 
=={{header|ERRE}}==
<syntaxhighlight lang=ERRE"erre">PROGRAM RATIONAL_ARITH
 
!
Line 1,119 ⟶ 1,261:
=={{header|F_Sharp|F#}}==
The F# Powerpack library defines the BigRational data type.
<syntaxhighlight lang="fsharp">type frac = Microsoft.FSharp.Math.BigRational
 
let perf n = 1N = List.fold (+) 0N (List.map (fun i -> if n % i = 0 then 1N/frac.FromInt(i) else 0N) [2..n])
Line 1,127 ⟶ 1,269:
=={{header|Factor}}==
<code>ratio</code> is a built-in numeric type.
<syntaxhighlight lang="factor">USING: generalizations io kernel math math.functions
math.primes.factors math.ranges prettyprint sequences ;
IN: rosetta-code.arithmetic-rational
Line 1,156 ⟶ 1,298:
=={{header|Fermat}}==
Fermat supports rational aritmetic natively.
<syntaxhighlight lang="fermat">
for n=2 to 2^19 by 2 do
s:=3/n;
Line 1,175 ⟶ 1,317:
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">\ Rationals can use any double cell operations: 2!, 2@, 2dup, 2swap, etc.
\ Uses the stack convention of the built-in "*/" for int * frac -> int
 
Line 1,216 ⟶ 1,358:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<syntaxhighlight lang="fortran">module module_rational
 
implicit none
Line 1,453 ⟶ 1,595:
end module module_rational</syntaxhighlight>
Example:
<syntaxhighlight lang="fortran">program perfect_numbers
 
use module_rational
Line 1,489 ⟶ 1,631:
=={{header|Frink}}==
Rational numbers are built into Frink and the numerator and denominator can be arbitrarily-sized. They are automatically simplified and collapsed into integers if necessary. All functions in the language can work with rational numbers. Rational numbers are treated as exact. Rational numbers can exist in complex numbers or intervals.
<syntaxhighlight lang="frink">
1/2 + 2/3
// 7/6 (approx. 1.1666666666666667)
Line 1,505 ⟶ 1,647:
=={{header|GAP}}==
Rational numbers are built-in.
<syntaxhighlight lang="gap">2/3 in Rationals;
# true
2/3 + 3/4;
Line 1,523 ⟶ 1,665:
 
Code here implements the perfect number test described in the task using the standard library.
<syntaxhighlight lang="go">package main
 
import (
Line 1,570 ⟶ 1,712:
=={{header|Groovy}}==
Groovy does not provide any built-in facility for rational arithmetic. However, it does support arithmetic operator overloading. Thus it is not too hard to build a fairly robust, complete, and intuitive rational number class, such as the following:
<syntaxhighlight lang="groovy">class Rational extends Number implements Comparable {
final BigInteger num, denom
 
Line 1,689 ⟶ 1,831:
 
The following ''RationalCategory'' class allows for modification of regular ''Number'' behavior when interacting with ''Rational''.
<syntaxhighlight lang="groovy">import org.codehaus.groovy.runtime.DefaultGroovyMethods
 
class RationalCategory {
Line 1,705 ⟶ 1,847:
 
Test Program (mixes the ''RationalCategory'' methods into the ''Number'' class):
<syntaxhighlight lang="groovy">Number.metaClass.mixin RationalCategory
 
def x = [5, 20] as Rational
Line 1,848 ⟶ 1,990:
</pre>
The following uses the ''Rational'' class, with ''RationalCategory'' mixed into ''Number'', to find all perfect numbers less than 2<sup>19</sup>:
<syntaxhighlight lang="groovy">Number.metaClass.mixin RationalCategory
 
def factorize = { target ->
Line 1,887 ⟶ 2,029:
=={{header|Haskell}}==
Haskell provides a <code>Rational</code> type, which is really an alias for <code>Ratio Integer</code> (<code>Ratio</code> being a polymorphic type implementing rational numbers for any <code>Integral</code> type of numerators and denominators). The fraction is constructed using the <code>%</code> operator.
<syntaxhighlight lang="haskell">import Data.Ratio ((%))
 
-- Prints the first N perfect numbers.
Line 1,917 ⟶ 2,059:
Additional procedures are implemented here to complete the task:
* 'makerat' (make), 'absrat' (abs), 'eqrat' (=), 'nerat' (~=), 'ltrat' (<), 'lerat' (<=), 'gerat' (>=), 'gtrat' (>)
<syntaxhighlight lang=Icon"icon">procedure main()
limit := 2^19
 
Line 1,967 ⟶ 2,109:
Testing absrat( (-1/1), ) ==> returned (1/1)</pre>
The following task functions are missing from the IPL:
<syntaxhighlight lang=Icon"icon">procedure verifyrat(p,r1,r2) #: verification tests for rational procedures
return write("Testing ",p,"( ",rat2str(r1),", ",rat2str(\r2) | &null," ) ==> ","returned " || rat2str(p(r1,r2)) | "failed")
end
Line 2,029 ⟶ 2,171:
link rational</syntaxhighlight>
The {{libheader|Icon Programming Library}} provides [http://www.cs.arizona.edu/icon/library/src/procs/rational.icn rational] and [http://www.cs.arizona.edu/icon/library/src/procs/numbers.icn gcd in numbers]. Record definition and usage is shown below:
<syntaxhighlight lang=Icon"icon"> record rational(numer, denom, sign) # rational type
 
addrat(r1,r2) # Add rational numbers r1 and r2.
Line 2,047 ⟶ 2,189:
=={{header|J}}==
Rational numbers in J may be formed from fixed precision integers by first upgrading them to arbitrary precision integers and then dividing them:
<syntaxhighlight lang=J"j"> (x: 3) % (x: -4)
_3r4
3 %&x: -4
Line 2,053 ⟶ 2,195:
Note that the syntax is analogous to the syntax for floating point numbers, but uses <code>r</code> to separate the numerator and denominator instead of <code>e</code> to separate the mantissa and exponent.
Thus:
<syntaxhighlight lang=J"j">
| _3r4 NB. absolute value
3r4
Line 2,085 ⟶ 2,227:
You can also coerce numbers directly to rational using x: (or to integer or floating point as appropriate using its inverse)
 
<syntaxhighlight lang=J"j"> x: 3%4
3r4
x:inv 3%4
Line 2,092 ⟶ 2,234:
Increment and decrement are also included in the language, but you could just as easily add or subtract 1:
 
<syntaxhighlight lang=J"j"> >: 3r4
7r4
<: 3r4
Line 2,099 ⟶ 2,241:
J does not encourage the use of specialized mutators, but those could also be defined:
 
<syntaxhighlight lang="j">mutadd=:adverb define
(m)=: (".m)+y
)
Line 2,109 ⟶ 2,251:
Note that the name whose association is being modified in this fashion needs to be quoted (or you can use an expression to provide the name):
 
<syntaxhighlight lang=J"j"> n=: 3r4
'n' mutadd 1
7r4
Line 2,120 ⟶ 2,262:
 
That said, note that J's floating point numbers work just fine for the stated problem:
<syntaxhighlight lang="j"> is_perfect_rational=: 2 = (1 + i.) +/@:%@([ #~ 0 = |) ]</syntaxhighlight>
Faster version (but the problem, as stated, is still tremendously inefficient):
<syntaxhighlight lang="j">factors=: */&>@{@((^ i.@>:)&.>/)@q:~&__
is_perfect_rational=: 2= +/@:%@,@factors</syntaxhighlight>
Exhaustive testing would take forever:
<syntaxhighlight lang="j"> I.is_perfect_rational@"0 i.2^19
6 28 496 8128
I.is_perfect_rational@x:@"0 i.2^19x
6 28 496 8128</syntaxhighlight>
More limited testing takes reasonable amounts of time:
<syntaxhighlight lang="j"> (#~ is_perfect_rational"0) (* <:@+:) 2^i.10x
6 28 496 8128</syntaxhighlight>
 
=={{header|Java}}==
Uses BigRational class: [[Arithmetic/Rational/Java]]
<syntaxhighlight lang="java">public class BigRationalFindPerfectNumbers {
public static void main(String[] args) {
int MAX_NUM = 1 << 19;
Line 2,201 ⟶ 2,343:
'''Unary'''
* `rabs` for unary `abs`
* `rfloor` like `floor`
* `rinv` for unary inverse
* `rminus` for unary minus
Line 2,225 ⟶ 2,368:
 
'''module {"name": "Rational"};'''
<syntaxhighlight lang="jq"># a and b are assumed to be non-zero integers
def gcd(a; b):
# subfunction expects [a,b] as input
Line 2,398 ⟶ 2,541:
end) | sub("0+$";"")
end
end;
 
# Assume . is an integer or in canonical form
def rfloor:
if type == "number" then r(.;1)
elif 0 == .n or (0 < .n and .n < .d) then r(0;1)
elif 0 < .n or (.n % .d == 0) then .d as $d | r(.n | idivide($d); 1)
else rminus( r( - .n; .d) | rfloor | rminus; 1)
end;
 
Line 2,404 ⟶ 2,555:
 
'''Perfect Numbers'''
<syntaxhighlight lang="jq">
# divisors as an unsorted stream
def divisors:
Line 2,439 ⟶ 2,590:
Julia has native support for rational numbers. Rationals are expressed as <tt>m//n</tt>, where <tt>m</tt> and <tt>n</tt> are integers. In addition to supporting most of the usual mathematical functions in a natural way on rationals, the methods <tt>num</tt> and <tt>den</tt> provide the fully reduced numerator and denominator of a rational value.
{{works with|Julia|1.2}}
<syntaxhighlight lang=Julia"julia">using Primes
divisors(n) = foldl((a, (p, e)) -> vcat((a * [p^i for i in 0:e]')...), factor(n), init=[1])
 
Line 2,455 ⟶ 2,606:
=={{header|Kotlin}}==
As it's not possible to define arbitrary symbols such as // to be operators in Kotlin, we instead use infix functions idiv (for Ints) and ldiv (for Longs) as a shortcut to generate Frac instances.
<syntaxhighlight lang="scala">// version 1.1.2
 
fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b)
Line 2,609 ⟶ 2,760:
=={{header|Liberty BASIC}}==
Testing all numbers up to 2 ^ 19 takes an excessively long time.
<syntaxhighlight lang="lb">
n=2^19
for testNumber=1 to n
Line 2,734 ⟶ 2,885:
=={{header|Lingo}}==
A new 'frac' data type can be implemented like this:
<syntaxhighlight lang="lingo">-- parent script "Frac"
property num
property denom
Line 2,782 ⟶ 2,933:
 
Lingo does not support overwriting built-in operators, so 'frac'-operators must be implemented as functions:
<syntaxhighlight lang="lingo">-- Frac library (movie script)
 
----------------------------------------
Line 2,866 ⟶ 3,017:
end</syntaxhighlight>
Usage:
<syntaxhighlight lang="lingo">f = frac(2,3)
put f.toString()
-- "2/3"
Line 2,881 ⟶ 3,032:
 
Finding perfect numbers:
<syntaxhighlight lang="lingo">-- in some movie script
----------------------------------------
-- Prints all perfect numbers up to n
Line 2,896 ⟶ 3,047:
end repeat
end</syntaxhighlight>
<syntaxhighlight lang="lingo">findPerfects(power(2, 19))
-- 6
-- 28
Line 2,903 ⟶ 3,054:
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function gcd(a,b) return a == 0 and b or gcd(b % a, a) end
 
do
Line 2,965 ⟶ 3,116:
http://www.rosettacode.org/wiki/M2000_Interpreter_rational_numbers
 
<syntaxhighlight lang=M2000"m2000 Interpreterinterpreter">
Class Rational {
\\ this is a compact version for this task
Line 2,991 ⟶ 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,027 ⟶ 3,186:
=={{header|Maple}}==
Maple has full built-in support for arithmetic with fractions (rational numbers). Fractions are treated like any other number in Maple.
<syntaxhighlight lang=Maple"maple">
> a := 3 / 5;
a := 3/5
Line 3,038 ⟶ 3,197:
</syntaxhighlight>
However, while you can enter a fraction such as "4/6", it will automatically be reduced so that the numerator and denominator have no common factor:
<syntaxhighlight lang=Maple"maple">
> b := 4 / 6;
b := 2/3
</syntaxhighlight>
All the standard arithmetic operators work with rational numbers. It is not necessary to call any special routines.
<syntaxhighlight lang=Maple"maple">
> a + b;
19
Line 3,067 ⟶ 3,226:
</syntaxhighlight>
Notice that fractions are treated as exact quantities; they are not converted to floats. However, you can get a floating point approximation to any desired accuracy by applying the function evalf to a fraction.
<syntaxhighlight lang=Maple"maple">
> evalf( 22 / 7 ); # default is 10 digits
3.142857143
Line 3,078 ⟶ 3,237:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Mathematica has full support for fractions built-in. If one divides two exact numbers it will be left as a fraction if it can't be simplified. Comparison, addition, division, product et cetera are built-in:
<syntaxhighlight lang=Mathematica"mathematica">4/16
3/8
8/4
Line 3,132 ⟶ 3,291:
3</pre>
As you can see, Mathematica automatically handles fraction as exact things, it doesn't evaluate the fractions to a float. It only does this when either the numerator or the denominator is not exact. I only showed integers above, but Mathematica can handle symbolic fraction in the same and complete way:
<syntaxhighlight lang=Mathematica"mathematica">c/(2 c)
(b^2 - c^2)/(b - c) // Cancel
1/2 + b/c // Together</syntaxhighlight>
gives back:
<syntaxhighlight lang=Mathematica"mathematica">1/2
b+c
(2 b+c) / (2 c)</syntaxhighlight>
Moreover it does simplification like Sin[x]/Cos[x] => Tan[x]. Division, addition, subtraction, powering and multiplication of a list (of any dimension) is automatically threaded over the elements:
<syntaxhighlight lang=Mathematica"mathematica">1+2*{1,2,3}^3</syntaxhighlight>
gives back:
<syntaxhighlight lang=Mathematica"mathematica">{3, 17, 55}</syntaxhighlight>
To check for perfect numbers in the range 1 to 2^25 we can use:
<syntaxhighlight lang=Mathematica"mathematica">found={};
CheckPerfect[num_Integer]:=If[Total[1/Divisors[num]]==2,AppendTo[found,num]];
Do[CheckPerfect[i],{i,1,2^25}];
found</syntaxhighlight>
gives back:
<syntaxhighlight lang=Mathematica"mathematica">{6, 28, 496, 8128, 33550336}</syntaxhighlight>
Final note; approximations of fractions to any precision can be found using the function N.
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">/* Rational numbers are builtin */
a: 3 / 11;
3/11
Line 3,193 ⟶ 3,352:
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import math
 
proc `^`[T](base, exp: T): T =
Line 3,303 ⟶ 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}}==
OCaml's Num library implements arbitrary-precision rational numbers:
<syntaxhighlight lang="ocaml">#load "nums.cma";;
open Num;;
 
Line 3,323 ⟶ 3,481:
done;;</syntaxhighlight>
[http://forge.ocamlcore.org/projects/pa-do/ Delimited overloading] can be used to make the arithmetic expressions more readable:
<syntaxhighlight lang="ocaml">let () =
for candidate = 2 to 1 lsl 19 do
let sum = ref Num.(1 / of_int candidate) in
Line 3,338 ⟶ 3,496:
 
First define the interface, hiding implementation details:
<syntaxhighlight lang="ocaml">(* interface *)
module type RATIO =
sig
Line 3,361 ⟶ 3,519:
 
then implement the module:
<syntaxhighlight lang="ocaml">(* implementation conforming to signature *)
module Frac : RATIO =
struct
Line 3,421 ⟶ 3,579:
 
Finally the use type defined by the module to perform the perfect number calculation:
<syntaxhighlight lang="ocaml">(* use the module to calculate perfect numbers *)
let () =
for i = 2 to 1 lsl 19 do
Line 3,449 ⟶ 3,607:
=={{header|Ol}}==
Otus Lisp has rational numbers built-in and integrated with all other number types.
<syntaxhighlight lang="scheme">
(define x 3/7)
(define y 9/11)
Line 3,508 ⟶ 3,666:
</pre>
=={{header|ooRexx}}==
<syntaxhighlight lang=ooRexx"oorexx">
loop candidate = 6 to 2**19
sum = .fraction~new(1, candidate)
Line 3,522 ⟶ 3,680:
end
 
::class fraction public inherit orderable
::method init
expose numerator denominator
Line 3,683 ⟶ 3,841:
=={{header|PARI/GP}}==
Pari handles rational arithmetic natively.
<syntaxhighlight lang="parigp">for(n=2,1<<19,
s=0;
fordiv(n,d,s+=1/d);
Line 3,691 ⟶ 3,849:
=={{header|Perl}}==
Perl's <code>Math::BigRat</code> core module implements arbitrary-precision rational numbers. The <code>bigrat</code> pragma can be used to turn on transparent BigRat support:
<syntaxhighlight lang="perl">use bigrat;
 
foreach my $candidate (2 .. 2**19) {
Line 3,708 ⟶ 3,866:
{{Trans|Tcl}}
Phix does not support operator overloading (I am strongly opposed to such nonsense), nor does it have a native fraction library, but it might look a bit like this.
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">without</span> <span style="color: #000000;">warning</span> <span style="color: #000080;font-style:italic;">-- (several unused routines in this code)</span>
Line 3,830 ⟶ 3,988:
Turned out to be slightly slower than native, but worth it for large number support.<br>
See also [[Bernoulli_numbers#Phix|Bernoulli_numbers]] for another example of mpqs in action.
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">is_perfect</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">)</span>
Line 3,875 ⟶ 4,033:
A naive addition algorithm is used, so the program is slow.
 
<syntaxhighlight lang=Picat"picat">
main =>
foreach (I in 2..2**19, is_perfect(I))
Line 3,904 ⟶ 4,062:
 
=={{header|PicoLisp}}==
<syntaxhighlight lang=PicoLisp"picolisp">(load "@lib/frac.l")
 
(for (N 2 (> (** 2 19) N) (inc N))
Line 3,930 ⟶ 4,088:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pli">*process source attributes xref or(!);
arat: Proc Options(main);
/*--------------------------------------------------------------------
Line 4,201 ⟶ 4,359:
=={{header|Prolog}}==
Prolog supports rational numbers, where P/Q is written as P rdiv Q.
<syntaxhighlight lang=Prolog"prolog">
divisor(N, Div) :-
Max is floor(sqrt(N)),
Line 4,239 ⟶ 4,397:
{{works with|Python|3.0}}
Python 3's standard library already implements a Fraction class:
<syntaxhighlight lang="python">from fractions import Fraction
 
for candidate in range(2, 2**19):
Line 4,250 ⟶ 4,408:
(candidate, int(sum), "perfect!" if sum == 1 else ""))</syntaxhighlight>
It might be implemented like this:
<syntaxhighlight lang="python">def lcm(a, b):
return a // gcd(a,b) * b
 
Line 4,290 ⟶ 4,448:
<code>factors</code> is defined at [[Factors of an integer#Quackery]].
 
<syntaxhighlight lang=Quackery"quackery"> [ $ "bigrat.qky" loadfile ] now!
 
[ -2 n->v rot
Line 4,312 ⟶ 4,470:
 
Example:
<syntaxhighlight lang="racket">
-> (* 1/7 14)
2
Line 4,321 ⟶ 4,479:
{{Works with|rakudo|2016.08}}
Raku supports rational arithmetic natively.
<syntaxhighlight lang=perl6"raku" line>(2..2**19).hyper.map: -> $candidate {
my $sum = 1 / $candidate;
for 2 .. ceiling(sqrt($candidate)) -> $factor {
Line 4,333 ⟶ 4,491:
}</syntaxhighlight>
Note also that ordinary decimal literals are stored as Rats, so the following loop always stops exactly on 10 despite 0.1 not being exactly representable in floating point:
<syntaxhighlight lang=perl6"raku" line>for 1.0, 1.1, 1.2 ... 10 { .say }</syntaxhighlight>
The arithmetic is all done in rationals, which are converted to floating-point just before display so that people don't have to puzzle out what 53/10 means.
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program implements a reasonably complete rational arithmetic (using fractions).*/
L=length(2**19 - 1) /*saves time by checking even numbers. */
do j=2 by 2 to 2**19 - 1; s=0 /*ignore unity (which can't be perfect)*/
Line 4,436 ⟶ 4,594:
=={{header|Ruby}}==
Ruby has a Rational class in it's core since 1.9.
<syntaxhighlight lang="ruby">
for candidate in 2 .. 2**19
sum = Rational(1, candidate)
Line 4,463 ⟶ 4,621:
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Neg};
 
Line 4,599 ⟶ 4,757:
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">class Rational(n: Long, d:Long) extends Ordered[Rational]
{
require(d!=0)
Line 4,644 ⟶ 4,802:
}</syntaxhighlight>
 
<syntaxhighlight lang="scala">def find_perfects():Unit=
{
for (candidate <- 2 until 1<<19)
Line 4,663 ⟶ 4,821:
Scheme has native rational numbers.
{{works with|Scheme|R5RS}}
<syntaxhighlight lang="scheme">; simply prints all the perfect numbers
(do ((candidate 2 (+ candidate 1))) ((>= candidate (expt 2 19)))
(let ((sum (/ 1 candidate)))
Line 4,683 ⟶ 4,841:
in the library [http://seed7.sourceforge.net/libraries/bigrat.htm bigrat.s7i].
 
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "rational.s7i";
 
Line 4,723 ⟶ 4,881:
=={{header|Sidef}}==
Sidef has built-in support for rational numbers.
<syntaxhighlight lang="ruby">for n in (1 .. 2**19) {
var frac = 0
 
Line 4,752 ⟶ 4,910:
=={{header|Slate}}==
Slate uses infinite-precision fractions transparently.
<syntaxhighlight lang="slate">54 / 7.
20 reciprocal.
(5 / 6) reciprocal.
Line 4,773 ⟶ 4,931:
</pre>
{{works with|GNU Smalltalk}} (and all others)
<syntaxhighlight lang="smalltalk">| sum |
2 to: (2 raisedTo: 19) do: [ :candidate |
sum := candidate reciprocal.
Line 4,794 ⟶ 4,952:
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
extension BinaryInteger {
Line 4,970 ⟶ 5,128:
{{libheader|Wren-rat}}
The latter module already contains support for rational number arithmetic.
<syntaxhighlight lang=ecmascript"wren">import "./math" for Int
import "./rat" for Rat
 
System.print("The following numbers (less than 2^19) are perfect:")
Line 4,991 ⟶ 5,149:
=={{header|zkl}}==
Enough of a Rational class for this task (ie implement the testing code "nicely").
<syntaxhighlight lang="zkl">class Rational{ // Weenie Rational class, can handle BigInts
fcn init(_a,_b){ var a=_a, b=_b; normalize(); }
fcn toString{
Line 5,021 ⟶ 5,179:
}
}</syntaxhighlight>
<syntaxhighlight lang="zkl">foreach p in ([2 .. (2).pow(19)]){
sum,limit := Rational(1,p), p.toFloat().sqrt();
foreach factor in ([2 .. limit]){
9,479

edits