Arithmetic/Rational: Difference between revisions

m
(add fermat)
m (→‎{{header|Wren}}: Minor tidy)
 
(19 intermediate revisions by 10 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>
 
=={{header|Action!}}==
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!">INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
TYPE Frac=[INT num,den]
 
REAL half
 
PROC PrintFrac(Frac POINTER x)
PrintI(x.num) Put('/) PrintI(x.den)
RETURN
 
INT FUNC Gcd(INT a,b)
INT tmp
 
IF a<b THEN
tmp=a a=b b=tmp
FI
 
WHILE b#0
DO
tmp=a MOD b
a=b
b=tmp
OD
RETURN (a)
 
PROC Init(INT n,d Frac POINTER res)
IF d>0 THEN
res.num=n res.den=d
ELSEIF d<0 THEN
res.num=-n res.den=-d
ELSE
Print("Denominator cannot be zero!")
Break()
FI
RETURN
 
PROC Assign(Frac POINTER x,res)
Init(x.num,x.den,res)
RETURN
 
PROC Neg(Frac POINTER x,res)
Init(-x.num,x.den,res)
RETURN
 
PROC Inverse(Frac POINTER x,res)
Init(x.den,x.num)
RETURN
 
PROC Abs(Frac POINTER x,res)
IF x.num<0 THEN
Neg(x,res)
ELSE
Assign(x,res)
FI
RETURN
 
PROC Add(Frac POINTER x,y,res)
INT common,xDen,yDen
common=Gcd(x.den,y.den)
xDen=x.den/common
yDen=y.den/common
Init(x.num*yDen+y.num*xDen,xDen*y.den,res)
RETURN
 
PROC Sub(Frac POINTER x,y,res)
Frac n
 
Neg(y,n) Add(x,n,res)
RETURN
 
PROC Mult(Frac POINTER x,y,res)
Init(x.num*y.num,x.den*y.den,res)
RETURN
 
PROC Div(Frac POINTER x,y,res)
Frac i
 
Inverse(y,i) Mult(x,i,res)
RETURN
 
BYTE FUNC Greater(Frac POINTER x,y)
Frac diff
 
Sub(x,y,diff)
IF diff.num>0 THEN
RETURN (1)
FI
RETURN (0)
 
BYTE FUNC Less(Frac POINTER x,y)
RETURN (Greater(y,x))
 
BYTE FUNC GreaterEqual(Frac POINTER x,y)
Frac diff
 
Sub(x,y,diff)
IF diff.num>=0 THEN
RETURN (1)
FI
RETURN (0)
 
BYTE FUNC LessEqual(Frac POINTER x,y)
RETURN (GreaterEqual(y,x))
 
BYTE FUNC Equal(Frac POINTER x,y)
Frac diff
 
Sub(x,y,diff)
IF diff.num=0 THEN
RETURN (1)
FI
RETURN (0)
 
BYTE FUNC NotEqual(Frac POINTER x,y)
IF Equal(x,y) THEN
RETURN (0)
FI
RETURN (1)
 
INT FUNC Sqrt(INT x)
REAL r1,r2
 
IF x=0 THEN
RETURN (0)
FI
IntToReal(x,r1)
Power(r1,half,r2)
RETURN (RealToInt(r2))
 
PROC Main()
DEFINE MAXINT="32767"
INT i,f,max2
Frac sum,tmp1,tmp2,tmp3,one
 
Put(125) PutE() ;clear screen
ValR("0.5",half)
Init(1,1,one)
FOR i=2 TO MAXINT
DO
Init(1,i,sum) ;sum=1/i
max2=Sqrt(i)
FOR f=2 TO max2
DO
IF i MOD f=0 THEN
Init(1,f,tmp1) ;tmp1=1/f
Add(sum,tmp1,tmp2) ;tmp2=sum+1/f
Init(f,i,tmp3) ;tmp3=f/i
Add(tmp2,tmp3,sum) ;sum=sum+1/f+f/i
FI
OD
 
IF Equal(sum,one) THEN
PrintF("%I is perfect%E",i)
FI
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Rational.png Screenshot from Atari 8-bit computer]
<pre>
6 is perfect
28 is perfect
496 is perfect
8128 is perfect
</pre>
 
=={{header|Ada}}==
Line 30 ⟶ 200:
{{works with|ALGOL 68|Standard - no extensions to language used}}
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
<langsyntaxhighlight lang="algol68"> MODE FRAC = STRUCT( INT num #erator#, den #ominator#);
FORMAT frac repr = $g(-0)"//"g(-0)$;
Line 160 ⟶ 330:
candidate, ENTIER sum, real sum, ENTIER sum = 1))
FI
OD</langsyntaxhighlight>
{{out}}
<pre>
Line 173 ⟶ 343:
Sum of reciprocal factors of 523776 = 2 exactly, about 2.0000000000000000000000000005
</pre>
 
=={{header|Arturo}}==
 
Arturo comes with built-in support for rational numbers.
 
<syntaxhighlight lang="rebol">a: to :rational [1 2]
b: to :rational [3 4]
 
print ["a:" a]
print ["b:" b]
 
print ["a + b :" a + b]
print ["a - b :" a - b]
print ["a * b :" a * b]
print ["a / b :" a / b]
print ["a // b :" a // b]
print ["a % b :" a % b]
 
print ["reciprocal b:" reciprocal b]
print ["neg a:" neg a]
 
print ["pi ~=" to :rational 3.14]</syntaxhighlight>
 
{{out}}
 
<pre>a: 1/2
b: 3/4
a + b : 5/4
a - b : -1/4
a * b : 3/8
a / b : 2/3
a // b : 2/3
a % b : 1/2
reciprocal b: 4/3
neg a: -1/2
pi ~= 157/50</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> *FLOAT64
DIM frac{num, den}
DIM Sum{} = frac{}, Kf{} = frac{}, One{} = frac{}
Line 237 ⟶ 443:
a.num /= a : a.den /= a
IF a.den < 0 a.num *= -1 : a.den *= -1
ENDPROC</langsyntaxhighlight>
Output:
<pre>
Line 248 ⟶ 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.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#define FMT "%lld"
Line 316 ⟶ 522:
 
return 0;
}</langsyntaxhighlight>
See [[Rational Arithmetic/C]]
 
=={{header|C sharp|C#}}==
<div style="text-align:right;font-size:7pt">''<nowiki>[</nowiki>This section is included from [[Arithmetic/Rational/C sharp|a subpage]] and should be edited there, not here.<nowiki>]</nowiki>''</div>
{{:Arithmetic/Rational/C sharp}}
Line 326 ⟶ 532:
{{libheader|Boost}}
Boost provides a rational number template.
<langsyntaxhighlight lang="cpp">#include <iostream>
#include "math.h"
#include "boost/rational.hpp"
Line 352 ⟶ 558:
}
return 0;
}</langsyntaxhighlight>
 
===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.
<langsyntaxhighlight Clojurelang="clojure">user> 22/7
22/7
user> 34/2
17
user> (+ 37/5 42/9)
181/15</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="lisp">(loop for candidate from 2 below (expt 2 19)
for sum = (+ (/ candidate)
(loop for factor from 2 to (isqrt candidate)
Line 371 ⟶ 718:
sum (+ (/ factor) (/ (floor candidate factor)))))
when (= sum 1)
collect candidate)</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.bigint, std.traits, std.conv;
 
// std.numeric.gcd doesn't work with BigInt.
Line 557 ⟶ 904:
}
}
}</langsyntaxhighlight>
Use the <code>-version=rational_arithmetic_main</code> compiler switch to run the test code.
{{out}}
Line 574 ⟶ 921:
{{libheader| Boost.Rational}}[[https://github.com/MaiconSoft/DelphiBoostLib]]
{{Trans|C#}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Arithmetic_Rational;
 
Line 605 ⟶ 952:
end;
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre>6 is perfect
Line 613 ⟶ 960:
=={{header|EchoLisp}}==
EchoLisp supports rational numbers as native type. "Big" rational i.e bigint/bigint are not supported.
<langsyntaxhighlight lang="lisp">
;; Finding perfect numbers
(define (sum/inv n) ;; look for div's in [2..sqrt(n)] and add 1/n
Line 620 ⟶ 967:
(when (zero? (modulo n i ))
(set! acc (+ acc (/ i) (/ i n))))))
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="lisp">
;; rational operations
(+ 1/42 1/666) → 59/2331
Line 640 ⟶ 987:
🍏 🍒 🍓 496 is perfect.
🍏 🍒 🍓 8128 is perfect.
</syntaxhighlight>
</lang>
 
=={{header|Elisa}}==
<langsyntaxhighlight Elisalang="elisa">component RationalNumbers;
type Rational;
Rational(Numerator = integer, Denominater = integer) -> Rational;
Line 703 ⟶ 1,050:
else GCD (A, mod(B,A)) ];
 
end component RationalNumbers;</langsyntaxhighlight>
Tests
<langsyntaxhighlight Elisalang="elisa">use RationalNumbers;
 
PerfectNumbers( Limit = integer) -> multi(integer);
Line 718 ⟶ 1,065:
];
 
PerfectNumbers(10000)?</langsyntaxhighlight>
{{out}}
<pre>
Line 728 ⟶ 1,075:
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule Rational do
import Kernel, except: [div: 2]
Line 793 ⟶ 1,140:
[candidate, sum.numerator, (if sum.numerator == 1, do: "perfect!", else: "")]
end
end)</langsyntaxhighlight>
 
{{out}}
Line 809 ⟶ 1,156:
 
=={{header|ERRE}}==
<langsyntaxhighlight ERRElang="erre">PROGRAM RATIONAL_ARITH
 
!
Line 904 ⟶ 1,251:
IF RES% THEN PRINT(N;" is perfect") END IF
END FOR
END PROGRAM</langsyntaxhighlight>
{{out}}
<pre> 6 is perfect
Line 914 ⟶ 1,261:
=={{header|F_Sharp|F#}}==
The F# Powerpack library defines the BigRational data type.
<langsyntaxhighlight 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])
 
for i in 1..(1<<<19) do if (perf i) then printfn "%i is perfect" i</langsyntaxhighlight>
 
=={{header|Factor}}==
<code>ratio</code> is a built-in numeric type.
<langsyntaxhighlight lang="factor">USING: generalizations io kernel math math.functions
math.primes.factors math.ranges prettyprint sequences ;
IN: rosetta-code.arithmetic-rational
Line 942 ⟶ 1,289:
 
"Perfect numbers <= 2^19: " print
2 19 ^ [1,b] [ perfect? ] filter .</langsyntaxhighlight>
{{out}}
<pre>
Line 951 ⟶ 1,298:
=={{header|Fermat}}==
Fermat supports rational aritmetic natively.
<langsyntaxhighlight lang="fermat">
for n=2 to 2^19 by 2 do
s:=3/n;
Line 960 ⟶ 1,307:
od;
if s=2 then !!n fi;
od;</langsyntaxhighlight>
{{out}}
<pre>
Line 970 ⟶ 1,317:
 
=={{header|Forth}}==
<langsyntaxhighlight 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,007 ⟶ 1,354:
 
: rat-inc tuck + swap ;
: rat-dec tuck - swap ;</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">module module_rational
 
implicit none
Line 1,246 ⟶ 1,593:
end function rational_modulo
 
end module module_rational</langsyntaxhighlight>
Example:
<langsyntaxhighlight lang="fortran">program perfect_numbers
 
use module_rational
Line 1,275 ⟶ 1,622:
end do
 
end program perfect_numbers</langsyntaxhighlight>
{{out}}
<pre>6
Line 1,284 ⟶ 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.
<langsyntaxhighlight lang="frink">
1/2 + 2/3
// 7/6 (approx. 1.1666666666666667)
Line 1,296 ⟶ 1,643:
8^(1/3)
// 2 (note the exact integer result.)
</syntaxhighlight>
</lang>
 
=={{header|GAP}}==
Rational numbers are built-in.
<langsyntaxhighlight lang="gap">2/3 in Rationals;
# true
2/3 + 3/4;
# 17/12</langsyntaxhighlight>
 
=={{header|Go}}==
Line 1,318 ⟶ 1,665:
 
Code here implements the perfect number test described in the task using the standard library.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,349 ⟶ 1,696:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,365 ⟶ 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:
<langsyntaxhighlight lang="groovy">class Rational extends Number implements Comparable {
final BigInteger num, denom
 
Line 1,481 ⟶ 1,828:
"${num}//${denom}"
}
}</langsyntaxhighlight>
 
The following ''RationalCategory'' class allows for modification of regular ''Number'' behavior when interacting with ''Rational''.
<langsyntaxhighlight lang="groovy">import org.codehaus.groovy.runtime.DefaultGroovyMethods
 
class RationalCategory {
Line 1,497 ⟶ 1,844:
: DefaultGroovyMethods.asType(a, type)
}
}</langsyntaxhighlight>
 
Test Program (mixes the ''RationalCategory'' methods into the ''Number'' class):
<langsyntaxhighlight lang="groovy">Number.metaClass.mixin RationalCategory
 
def x = [5, 20] as Rational
Line 1,586 ⟶ 1,933:
catch (Throwable t) { println t.message }
try { println (α as char) }
catch (Throwable t) { println t.message }</langsyntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll;">1//4
Line 1,643 ⟶ 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>:
<langsyntaxhighlight lang="groovy">Number.metaClass.mixin RationalCategory
 
def factorize = { target ->
Line 1,667 ⟶ 2,014:
def trackProgress = { if ((it % (100*1000)) == 0) { println it } else if ((it % 1000) == 0) { print "." } }
 
(1..(2**19)).findResults { trackProgress(it); perfect(it) }.each { println(); print it }</langsyntaxhighlight>
{{out}}
<pre>...................................................................................................100000
Line 1,682 ⟶ 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.
<langsyntaxhighlight lang="haskell">import Data.Ratio ((%))
 
-- Prints the first N perfect numbers.
Line 1,700 ⟶ 2,047:
| factor <- [2 .. floor (sqrt (fromIntegral candidate))]
, candidate `mod` factor == 0 ]
</syntaxhighlight>
</lang>
 
For a sample implementation of <code>Ratio</code>, see [http://www.haskell.org/onlinereport/ratio.html the Haskell 98 Report].
Line 1,712 ⟶ 2,059:
Additional procedures are implemented here to complete the task:
* 'makerat' (make), 'absrat' (abs), 'eqrat' (=), 'nerat' (~=), 'ltrat' (<), 'lerat' (<=), 'gerat' (>=), 'gtrat' (>)
<langsyntaxhighlight Iconlang="icon">procedure main()
limit := 2^19
 
Line 1,745 ⟶ 2,092:
if rsum.numer = rsum.denom = 1 then
return c
end</langsyntaxhighlight>
{{out}}
<pre>Perfect numbers up to 524288 (using rational arithmetic):
Line 1,762 ⟶ 2,109:
Testing absrat( (-1/1), ) ==> returned (1/1)</pre>
The following task functions are missing from the IPL:
<langsyntaxhighlight Iconlang="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 1,822 ⟶ 2,169:
end
 
link rational</langsyntaxhighlight>
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:
<langsyntaxhighlight Iconlang="icon"> record rational(numer, denom, sign) # rational type
 
addrat(r1,r2) # Add rational numbers r1 and r2.
Line 1,838 ⟶ 2,185:
subrat(r1,r2) # Subtract rational numbers r1 and r2.
 
gcd(i, j) # returns greatest common divisor of i and j</langsyntaxhighlight>
 
=={{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:
<langsyntaxhighlight Jlang="j"> (x: 3) % (x: -4)
_3r4
3 %&x: -4
_3r4</langsyntaxhighlight>
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">
<lang J>
| _3r4 NB. absolute value
3r4
Line 1,876 ⟶ 2,223:
0
3r4 ~: 2r5 NB. not equal
1</langsyntaxhighlight>
 
You can also coerce numbers directly to rational using x: (or to integer or floating point as appropriate using its inverse)
 
<langsyntaxhighlight Jlang="j"> x: 3%4
3r4
x:inv 3%4
0.75</langsyntaxhighlight>
 
Increment and decrement are also included in the language, but you could just as easily add or subtract 1:
 
<langsyntaxhighlight Jlang="j"> >: 3r4
7r4
<: 3r4
_1r4</langsyntaxhighlight>
 
J does not encourage the use of specialized mutators, but those could also be defined:
 
<langsyntaxhighlight lang="j">mutadd=:adverb define
(m)=: (".m)+y
)
Line 1,900 ⟶ 2,247:
mutsub=:adverb define
(m)=: (".m)-y
)</langsyntaxhighlight>
 
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):
 
<langsyntaxhighlight Jlang="j"> n=: 3r4
'n' mutadd 1
7r4
Line 1,910 ⟶ 2,257:
3r4
'n' mutsub 1
_1r4</langsyntaxhighlight>
 
(Bare words to the immediate left of the assignment operator are implicitly quoted - but this is just syntactic sugar because that is such an overwhelmingly common case.)
 
That said, note that J's floating point numbers work just fine for the stated problem:
<langsyntaxhighlight lang="j"> is_perfect_rational=: 2 = (1 + i.) +/@:%@([ #~ 0 = |) ]</langsyntaxhighlight>
Faster version (but the problem, as stated, is still tremendously inefficient):
<langsyntaxhighlight lang="j">factors=: */&>@{@((^ i.@>:)&.>/)@q:~&__
is_perfect_rational=: 2= +/@:%@,@factors</langsyntaxhighlight>
Exhaustive testing would take forever:
<langsyntaxhighlight 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</langsyntaxhighlight>
More limited testing takes reasonable amounts of time:
<langsyntaxhighlight lang="j"> (#~ is_perfect_rational"0) (* <:@+:) 2^i.10x
6 28 496 8128</langsyntaxhighlight>
 
=={{header|Java}}==
Uses BigRational class: [[Arithmetic/Rational/Java]]
<langsyntaxhighlight lang="java">public class BigRationalFindPerfectNumbers {
public static void main(String[] args) {
int MAX_NUM = 1 << 19;
Line 1,956 ⟶ 2,303:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Searching for perfect numbers in the range [1, 524287]
Line 1,996 ⟶ 2,343:
'''Unary'''
* `rabs` for unary `abs`
* `rfloor` like `floor`
* `rinv` for unary inverse
* `rminus` for unary minus
Line 2,020 ⟶ 2,368:
 
'''module {"name": "Rational"};'''
<langsyntaxhighlight lang="jq"># a and b are assumed to be non-zero integers
def gcd(a; b):
# subfunction expects [a,b] as input
Line 2,193 ⟶ 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;
 
# pretty print ala Julia
def rpp: "\(.n) // \(.d)";</langsyntaxhighlight>
 
'''Perfect Numbers'''
<syntaxhighlight lang="jq">
<lang jq>
# divisors as an unsorted stream
def divisors:
Line 2,222 ⟶ 2,578:
# Example:
range(1;pow(2;19)) | select( is_perfect )
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,234 ⟶ 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}}
<langsyntaxhighlight Julialang="julia">using Primes
divisors(n) = foldl((a, (p, e)) -> vcat((a * [p^i for i in 0:e]')...), factor(n), init=[1])
 
Line 2,241 ⟶ 2,597:
lo, hi = 2, 2^19
println("Perfect numbers between ", lo, " and ", hi, ": ", collect(filter(isperfect, lo:hi)))
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,250 ⟶ 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.
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b)
Line 2,376 ⟶ 2,732:
}
println()
}</langsyntaxhighlight>
 
{{out}}
Line 2,404 ⟶ 2,760:
=={{header|Liberty BASIC}}==
Testing all numbers up to 2 ^ 19 takes an excessively long time.
<syntaxhighlight lang="lb">
<lang lb>
n=2^19
for testNumber=1 to n
Line 2,525 ⟶ 2,881:
end if
end function
</syntaxhighlight>
</lang>
 
=={{header|Lingo}}==
A new 'frac' data type can be implemented like this:
<langsyntaxhighlight lang="lingo">-- parent script "Frac"
property num
property denom
Line 2,574 ⟶ 2,930:
if a > b then return me._gcd(b, a mod b)
return me._gcd(a, b mod a)
end</langsyntaxhighlight>
 
Lingo does not support overwriting built-in operators, so 'frac'-operators must be implemented as functions:
<langsyntaxhighlight lang="lingo">-- Frac library (movie script)
 
----------------------------------------
Line 2,659 ⟶ 3,015:
diff = fSub(a, b)
return diff.num<=0
end</langsyntaxhighlight>
Usage:
<langsyntaxhighlight lang="lingo">f = frac(2,3)
put f.toString()
-- "2/3"
Line 2,673 ⟶ 3,029:
f = frac(23)
put f.toString()
-- "23/1"</langsyntaxhighlight>
 
Finding perfect numbers:
<langsyntaxhighlight lang="lingo">-- in some movie script
----------------------------------------
-- Prints all perfect numbers up to n
Line 2,690 ⟶ 3,046:
if sum.denom = sum.num then put i
end repeat
end</langsyntaxhighlight>
<langsyntaxhighlight lang="lingo">findPerfects(power(2, 19))
-- 6
-- 28
-- 496
-- 8128</langsyntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function gcd(a,b) return a == 0 and b or gcd(b % a, a) end
 
do
Line 2,755 ⟶ 3,111:
return table.concat(ret, '\n')
end
print(findperfs(2^19))</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
http://www.rosettacode.org/wiki/M2000_Interpreter_rational_numbers
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Class Rational {
\\ this is a compact version for this task
Line 2,786 ⟶ 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 2,818 ⟶ 3,182:
}
Print timecount
</syntaxhighlight>
</lang>
 
=={{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">
<lang Maple>
> a := 3 / 5;
a := 3/5
Line 2,831 ⟶ 3,195:
> denom( a );
5
</syntaxhighlight>
</lang>
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">
<lang Maple>
> b := 4 / 6;
b := 2/3
</syntaxhighlight>
</lang>
All the standard arithmetic operators work with rational numbers. It is not necessary to call any special routines.
<syntaxhighlight lang="maple">
<lang Maple>
> a + b;
19
Line 2,860 ⟶ 3,224:
> a - 1;
-2/5
</syntaxhighlight>
</lang>
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">
<lang Maple>
> evalf( 22 / 7 ); # default is 10 digits
3.142857143
Line 2,869 ⟶ 3,233:
3.142857142857142857142857142857142857142857142857142857142857142857\
142857142857142857142857142857143
</syntaxhighlight>
</lang>
 
=={{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">4/16
<lang Mathematica>4/16
3/8
8/4
Line 2,898 ⟶ 3,262:
 
Numerator[6/9]
Denominator[6/9]</langsyntaxhighlight>
gives back:
<pre>1/4
Line 2,927 ⟶ 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:
<langsyntaxhighlight Mathematicalang="mathematica">c/(2 c)
(b^2 - c^2)/(b - c) // Cancel
1/2 + b/c // Together</langsyntaxhighlight>
gives back:
<syntaxhighlight lang="mathematica">1/2
<lang Mathematica>1/2
b+c
(2 b+c) / (2 c)</langsyntaxhighlight>
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:
<langsyntaxhighlight Mathematicalang="mathematica">1+2*{1,2,3}^3</langsyntaxhighlight>
gives back:
<syntaxhighlight lang Mathematica="mathematica">{3, 17, 55}</langsyntaxhighlight>
To check for perfect numbers in the range 1 to 2^25 we can use:
<langsyntaxhighlight Mathematicalang="mathematica">found={};
CheckPerfect[num_Integer]:=If[Total[1/Divisors[num]]==2,AppendTo[found,num]];
Do[CheckPerfect[i],{i,1,2^25}];
found</langsyntaxhighlight>
gives back:
<langsyntaxhighlight Mathematicalang="mathematica">{6, 28, 496, 8128, 33550336}</langsyntaxhighlight>
Final note; approximations of fractions to any precision can be found using the function N.
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">/* Rational numbers are builtin */
a: 3 / 11;
3/11
Line 2,977 ⟶ 3,341:
 
ratnump(a);
true</langsyntaxhighlight>
 
=={{header|Modula-2}}==
Line 2,988 ⟶ 3,352:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import math
 
proc `^`[T](base, exp: T): T =
Line 3,085 ⟶ 3,449:
if sum.den == 1:
echo "Sum of recipr. factors of ",candidate," = ",sum.num," exactly ",
if sum.num == 1: "perfect!" else: ""</langsyntaxhighlight>
Output:
<pre>Sum of recipr. factors of 6 = 1 exactly perfect!
Line 3,098 ⟶ 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:
<langsyntaxhighlight lang="ocaml">#load "nums.cma";;
open Num;;
 
Line 3,116 ⟶ 3,479:
Printf.printf "Sum of recipr. factors of %d = %d exactly %s\n%!"
candidate (int_of_num !sum) (if int_of_num !sum = 1 then "perfect!" else "")
done;;</langsyntaxhighlight>
[http://forge.ocamlcore.org/projects/pa-do/ Delimited overloading] can be used to make the arithmetic expressions more readable:
<langsyntaxhighlight lang="ocaml">let () =
for candidate = 2 to 1 lsl 19 do
let sum = ref Num.(1 / of_int candidate) in
Line 3,128 ⟶ 3,491:
Printf.printf "Sum of recipr. factors of %d = %d exactly %s\n%!"
candidate Num.(to_int !sum) (if Num.(!sum = 1) then "perfect!" else "")
done</langsyntaxhighlight>
 
A type for rational numbers might be implemented like this:
 
First define the interface, hiding implementation details:
<langsyntaxhighlight lang="ocaml">(* interface *)
module type RATIO =
sig
Line 3,153 ⟶ 3,516:
val ( */ ) : t -> t -> t
val ( // ) : t -> t -> t
end</langsyntaxhighlight>
 
then implement the module:
<langsyntaxhighlight lang="ocaml">(* implementation conforming to signature *)
module Frac : RATIO =
struct
Line 3,213 ⟶ 3,576:
let ( -/ ) {num=n1; den=d1} {num=n2; den=d2} =
norm { num = n1*~d2 -~ n2*~d1; den = d1*~d2 }
end</langsyntaxhighlight>
 
Finally the use type defined by the module to perform the perfect number calculation:
<langsyntaxhighlight lang="ocaml">(* use the module to calculate perfect numbers *)
let () =
for i = 2 to 1 lsl 19 do
Line 3,229 ⟶ 3,592:
Printf.printf "Sum of reciprocal factors of %d = %s exactly %s\n%!"
i (Frac.to_string !sum) (if Frac.to_string !sum = "1" then "perfect!" else "")
done</langsyntaxhighlight>
which produces this output:
 
Line 3,244 ⟶ 3,607:
=={{header|Ol}}==
Otus Lisp has rational numbers built-in and integrated with all other number types.
<langsyntaxhighlight lang="scheme">
(define x 3/7)
(define y 9/11)
Line 3,280 ⟶ 3,643:
(print candidate (if (eq? sum 1) ", perfect" "")))))
(liota 2 1 (expt 2 15)))
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,303 ⟶ 3,666:
</pre>
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
<lang ooRexx>
loop candidate = 6 to 2**19
sum = .fraction~new(1, candidate)
Line 3,317 ⟶ 3,680:
end
 
::class fraction public inherit orderable
::method init
expose numerator denominator
Line 3,467 ⟶ 3,830:
 
::requires rxmath library
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,478 ⟶ 3,841:
=={{header|PARI/GP}}==
Pari handles rational arithmetic natively.
<langsyntaxhighlight lang="parigp">for(n=2,1<<19,
s=0;
fordiv(n,d,s+=1/d);
if(s==2,print(n))
)</langsyntaxhighlight>
 
=={{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:
<langsyntaxhighlight lang="perl">use bigrat;
 
foreach my $candidate (2 .. 2**19) {
Line 3,498 ⟶ 3,861:
print "Sum of recipr. factors of $candidate = $sum exactly ", ($sum == 1 ? "perfect!" : ""), "\n";
}
}</langsyntaxhighlight>
 
=={{header|Phix}}==
{{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.
<!--<langsyntaxhighlight Phixlang="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,611 ⟶ 3,974:
<span style="color: #000000;">get_perfect_numbers</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 3,625 ⟶ 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.
<!--<langsyntaxhighlight Phixlang="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,655 ⟶ 4,018:
<span style="color: #000000;">get_perfect_numbers</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 3,666 ⟶ 4,029:
</pre>
<small>Note that power(2,19) took over 270s under mpfr.js, so reduced to power(2,13) on that platform, making it finish in 0.99s</small>
 
=={{header|Picat}}==
A naive addition algorithm is used, so the program is slow.
 
<syntaxhighlight lang="picat">
main =>
foreach (I in 2..2**19, is_perfect(I))
println(I)
end.
is_perfect(N) => sum_rationals([$frac(1,D) : D in divisors(N)]) == $frac(2,1).
 
divisors(N) = [I : I in 1..N, N mod I == 0].
 
add(frac(A,B), frac(C,D)) = new_fract(A*D+B*C, B*D).
 
new_fract(A,B) = $frac(Num, Den) =>
G = gcd(A,B),
Num = A // G,
Den = B // G.
 
sum_rationals([X]) = X.
sum_rationals([X,Y|T]) = sum_rationals([add(X,Y)|T]).
</syntaxhighlight>
{{out}}
<pre>
6
28
496
8128
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/frac.l")
 
(for (N 2 (> (** 2 19) N) (inc N))
Line 3,681 ⟶ 4,075:
"Perfect " N
", sum is " (car Sum)
(and (= 1 (car Sum)) ": perfect") ) ) ) )</langsyntaxhighlight>
{{out}}
<pre>Perfect 6, sum is 1: perfect
Line 3,694 ⟶ 4,088:
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">*process source attributes xref or(!);
arat: Proc Options(main);
/*--------------------------------------------------------------------
Line 3,939 ⟶ 4,333:
End lcm;
 
End;</langsyntaxhighlight>
{{out}}
<pre>First solve the task at hand
Line 3,965 ⟶ 4,359:
=={{header|Prolog}}==
Prolog supports rational numbers, where P/Q is written as P rdiv Q.
<syntaxhighlight lang="prolog">
<lang Prolog>
divisor(N, Div) :-
Max is floor(sqrt(N)),
Line 3,992 ⟶ 4,386:
 
?- main.
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 4,003 ⟶ 4,397:
{{works with|Python|3.0}}
Python 3's standard library already implements a Fraction class:
<langsyntaxhighlight lang="python">from fractions import Fraction
 
for candidate in range(2, 2**19):
Line 4,012 ⟶ 4,406:
if sum.denominator == 1:
print("Sum of recipr. factors of %d = %d exactly %s" %
(candidate, int(sum), "perfect!" if sum == 1 else ""))</langsyntaxhighlight>
It might be implemented like this:
<langsyntaxhighlight lang="python">def lcm(a, b):
return a // gcd(a,b) * b
 
Line 4,046 ⟶ 4,440:
return float(self.numerator / self.denominator)
def __int__(self):
return (self.numerator // self.denominator)</langsyntaxhighlight>
 
=={{header|Quackery}}==
Line 4,054 ⟶ 4,448:
<code>factors</code> is defined at [[Factors of an integer#Quackery]].
 
<langsyntaxhighlight Quackerylang="quackery"> [ $ "bigrat.qky" loadfile ] now!
 
[ -2 n->v rot
Line 4,061 ⟶ 4,455:
v0= ] is perfect ( n -> b )
 
19 bit times [ i^ perfect if [ i^ echo cr ] ]</langsyntaxhighlight>
 
{{out}}
Line 4,076 ⟶ 4,470:
 
Example:
<langsyntaxhighlight lang="racket">
-> (* 1/7 14)
2
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 4,085 ⟶ 4,479:
{{Works with|rakudo|2016.08}}
Raku supports rational arithmetic natively.
<syntaxhighlight lang="raku" perl6line>(2..2**19).hyper.map: -> $candidate {
my $sum = 1 / $candidate;
for 2 .. ceiling(sqrt($candidate)) -> $factor {
Line 4,095 ⟶ 4,489:
say "Sum of reciprocal factors of $candidate = $sum exactly", ($sum == 1 ?? ", perfect!" !! ".");
}
}</langsyntaxhighlight>
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="raku" perl6line>for 1.0, 1.1, 1.2 ... 10 { .say }</langsyntaxhighlight>
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}}==
<langsyntaxhighlight 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,187 ⟶ 4,581:
gcd: procedure; parse arg x,y; if x=0 then return y; do until _==0; _=x//y; x=y; y=_; end; return x
lcm: procedure; parse arg x,y; if y=0 then return 0; x=x*y/gcd(x, y); return x
p: return word( arg(1), 1)</langsyntaxhighlight>
Programming note: &nbsp; the &nbsp; '''eDivs, gcd, lcm''' &nbsp; functions are optimized functions for this program only.
 
Line 4,200 ⟶ 4,594:
=={{header|Ruby}}==
Ruby has a Rational class in it's core since 1.9.
<langsyntaxhighlight lang="ruby">
for candidate in 2 .. 2**19
sum = Rational(1, candidate)
Line 4,212 ⟶ 4,606:
[candidate, sum.to_i, sum == 1 ? "perfect!" : ""]
end
end</langsyntaxhighlight>
{{out}}
<pre>
Line 4,227 ⟶ 4,621:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Neg};
 
Line 4,360 ⟶ 4,754:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">class Rational(n: Long, d:Long) extends Ordered[Rational]
{
require(d!=0)
Line 4,406 ⟶ 4,800:
def apply(n:Long)=new Rational(n)
implicit def longToRational(i:Long)=new Rational(i)
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="scala">def find_perfects():Unit=
{
for (candidate <- 2 until 1<<19)
Line 4,422 ⟶ 4,816:
printf("Perfect number %d sum is %s\n", candidate, sum)
}
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
Scheme has native rational numbers.
{{works with|Scheme|R5RS}}
<langsyntaxhighlight lang="scheme">; simply prints all the perfect numbers
(do ((candidate 2 (+ candidate 1))) ((>= candidate (expt 2 19)))
(let ((sum (/ 1 candidate)))
Line 4,434 ⟶ 4,828:
(set! sum (+ sum (/ 1 factor) (/ factor candidate)))))
(if (= 1 (denominator sum))
(begin (display candidate) (newline)))))</langsyntaxhighlight>
It might be implemented like this:
 
Line 4,447 ⟶ 4,841:
in the library [http://seed7.sourceforge.net/libraries/bigrat.htm bigrat.s7i].
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "rational.s7i";
 
Line 4,475 ⟶ 4,869:
end if;
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 4,487 ⟶ 4,881:
=={{header|Sidef}}==
Sidef has built-in support for rational numbers.
<langsyntaxhighlight lang="ruby">for n in (1 .. 2**19) {
var frac = 0
 
Line 4,499 ⟶ 4,893:
}"
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 4,516 ⟶ 4,910:
=={{header|Slate}}==
Slate uses infinite-precision fractions transparently.
<langsyntaxhighlight lang="slate">54 / 7.
20 reciprocal.
(5 / 6) reciprocal.
(5 / 6) as: Float.</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
Line 4,537 ⟶ 4,931:
</pre>
{{works with|GNU Smalltalk}} (and all others)
<langsyntaxhighlight lang="smalltalk">| sum |
2 to: (2 raisedTo: 19) do: [ :candidate |
sum := candidate reciprocal.
Line 4,554 ⟶ 4,948:
ifFalse: [ ' ' ] }) displayNl
]
].</langsyntaxhighlight>
 
=={{header|Swift}}==
 
<langsyntaxhighlight lang="swift">import Foundation
 
extension BinaryInteger {
Line 4,713 ⟶ 5,107:
print("\(candidate) is perfect")
}
}</langsyntaxhighlight>
 
{{out}}
Line 4,734 ⟶ 5,128:
{{libheader|Wren-rat}}
The latter module already contains support for rational number arithmetic.
<langsyntaxhighlight ecmascriptlang="wren">import "./math" for Int
import "./rat" for Rat
 
System.print("The following numbers (less than 2^19) are perfect:")
Line 4,742 ⟶ 5,136:
for (j in Int.properDivisors(i)[1..-1]) sum = sum + Rat.new(1, j)
if (sum == Rat.one) System.print(" %(i)")
}</langsyntaxhighlight>
 
{{out}}
Line 4,755 ⟶ 5,149:
=={{header|zkl}}==
Enough of a Rational class for this task (ie implement the testing code "nicely").
<langsyntaxhighlight lang="zkl">class Rational{ // Weenie Rational class, can handle BigInts
fcn init(_a,_b){ var a=_a, b=_b; normalize(); }
fcn toString{
Line 4,784 ⟶ 5,178:
else b==1 and a==r;
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">foreach p in ([2 .. (2).pow(19)]){
sum,limit := Rational(1,p), p.toFloat().sqrt();
foreach factor in ([2 .. limit]){
Line 4,792 ⟶ 5,186:
if(sum.b==1) println("Sum of recipr. factors of %6s = %s exactly%s"
.fmt(p, sum, (sum==1) and ", perfect." or "."));
}</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits