Arithmetic/Rational: Difference between revisions
Content added Content deleted
(Swift: handle negative printing better) |
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
||
Line 2,078: | Line 2,078: | ||
6 28 496 8128 |
6 28 496 8128 |
||
</pre> |
</pre> |
||
=={{header|Liberty BASIC}}== |
|||
Testing all numbers up to 2 ^ 19 takes an excessively long time. |
|||
<lang lb> |
|||
n=2^19 |
|||
for testNumber=1 to n |
|||
sum$=castToFraction$(0) |
|||
for factorTest=1 to sqr(testNumber) |
|||
if GCD(factorTest,testNumber)=factorTest then sum$=add$(sum$,add$(reciprocal$(castToFraction$(factorTest)),reciprocal$(castToFraction$(testNumber/factorTest)))) |
|||
next factorTest |
|||
if equal(sum$,castToFraction$(2))=1 then print testNumber |
|||
next testNumber |
|||
end |
|||
function abs$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=abs(aNumerator) |
|||
bDenominator=abs(aDenominator) |
|||
b$=str$(bNumerator)+"/"+str$(bDenominator) |
|||
abs$=simplify$(b$) |
|||
end function |
|||
function negate$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=-1*aNumerator |
|||
bDenominator=aDenominator |
|||
b$=str$(bNumerator)+"/"+str$(bDenominator) |
|||
negate$=simplify$(b$) |
|||
end function |
|||
function add$(a$,b$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=val(word$(b$,1,"/")) |
|||
bDenominator=val(word$(b$,2,"/")) |
|||
cNumerator=(aNumerator*bDenominator+bNumerator*aDenominator) |
|||
cDenominator=aDenominator*bDenominator |
|||
c$=str$(cNumerator)+"/"+str$(cDenominator) |
|||
add$=simplify$(c$) |
|||
end function |
|||
function subtract$(a$,b$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=val(word$(b$,1,"/")) |
|||
bDenominator=val(word$(b$,2,"/")) |
|||
cNumerator=(aNumerator*bDenominator-bNumerator*aDenominator) |
|||
cDenominator=aDenominator*bDenominator |
|||
c$=str$(cNumerator)+"/"+str$(cDenominator) |
|||
subtract$=simplify$(c$) |
|||
end function |
|||
function multiply$(a$,b$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=val(word$(b$,1,"/")) |
|||
bDenominator=val(word$(b$,2,"/")) |
|||
cNumerator=aNumerator*bNumerator |
|||
cDenominator=aDenominator*bDenominator |
|||
c$=str$(cNumerator)+"/"+str$(cDenominator) |
|||
multiply$=simplify$(c$) |
|||
end function |
|||
function divide$(a$,b$) |
|||
divide$=multiply$(a$,reciprocal$(b$)) |
|||
end function |
|||
function simplify$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
gcd=GCD(aNumerator,aDenominator) |
|||
if aNumerator<0 and aDenominator<0 then gcd=-1*gcd |
|||
bNumerator=aNumerator/gcd |
|||
bDenominator=aDenominator/gcd |
|||
b$=str$(bNumerator)+"/"+str$(bDenominator) |
|||
simplify$=b$ |
|||
end function |
|||
function reciprocal$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
reciprocal$=str$(aDenominator)+"/"+str$(aNumerator) |
|||
end function |
|||
function equal(a$,b$) |
|||
if simplify$(a$)=simplify$(b$) then equal=1:else equal=0 |
|||
end function |
|||
function castToFraction$(a) |
|||
do |
|||
exp=exp+1 |
|||
a=a*10 |
|||
loop until a=int(a) |
|||
castToFraction$=simplify$(str$(a)+"/"+str$(10^exp)) |
|||
end function |
|||
function castToReal(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
castToReal=aNumerator/aDenominator |
|||
end function |
|||
function castToInt(a$) |
|||
castToInt=int(castToReal(a$)) |
|||
end function |
|||
function GCD(a,b) |
|||
if a=0 then |
|||
GCD=1 |
|||
else |
|||
if a>=b then |
|||
while b |
|||
c = a |
|||
a = b |
|||
b = c mod b |
|||
GCD = abs(a) |
|||
wend |
|||
else |
|||
GCD=GCD(b,a) |
|||
end if |
|||
end if |
|||
end function |
|||
</lang> |
|||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
Line 2,309: | Line 2,434: | ||
print(findperfs(2^19))</lang> |
print(findperfs(2^19))</lang> |
||
=={{header|Liberty BASIC}}== |
|||
Testing all numbers up to 2 ^ 19 takes an excessively long time. |
|||
<lang lb> |
|||
n=2^19 |
|||
for testNumber=1 to n |
|||
sum$=castToFraction$(0) |
|||
for factorTest=1 to sqr(testNumber) |
|||
if GCD(factorTest,testNumber)=factorTest then sum$=add$(sum$,add$(reciprocal$(castToFraction$(factorTest)),reciprocal$(castToFraction$(testNumber/factorTest)))) |
|||
next factorTest |
|||
if equal(sum$,castToFraction$(2))=1 then print testNumber |
|||
next testNumber |
|||
end |
|||
function abs$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=abs(aNumerator) |
|||
bDenominator=abs(aDenominator) |
|||
b$=str$(bNumerator)+"/"+str$(bDenominator) |
|||
abs$=simplify$(b$) |
|||
end function |
|||
function negate$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=-1*aNumerator |
|||
bDenominator=aDenominator |
|||
b$=str$(bNumerator)+"/"+str$(bDenominator) |
|||
negate$=simplify$(b$) |
|||
end function |
|||
function add$(a$,b$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=val(word$(b$,1,"/")) |
|||
bDenominator=val(word$(b$,2,"/")) |
|||
cNumerator=(aNumerator*bDenominator+bNumerator*aDenominator) |
|||
cDenominator=aDenominator*bDenominator |
|||
c$=str$(cNumerator)+"/"+str$(cDenominator) |
|||
add$=simplify$(c$) |
|||
end function |
|||
function subtract$(a$,b$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=val(word$(b$,1,"/")) |
|||
bDenominator=val(word$(b$,2,"/")) |
|||
cNumerator=(aNumerator*bDenominator-bNumerator*aDenominator) |
|||
cDenominator=aDenominator*bDenominator |
|||
c$=str$(cNumerator)+"/"+str$(cDenominator) |
|||
subtract$=simplify$(c$) |
|||
end function |
|||
function multiply$(a$,b$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
bNumerator=val(word$(b$,1,"/")) |
|||
bDenominator=val(word$(b$,2,"/")) |
|||
cNumerator=aNumerator*bNumerator |
|||
cDenominator=aDenominator*bDenominator |
|||
c$=str$(cNumerator)+"/"+str$(cDenominator) |
|||
multiply$=simplify$(c$) |
|||
end function |
|||
function divide$(a$,b$) |
|||
divide$=multiply$(a$,reciprocal$(b$)) |
|||
end function |
|||
function simplify$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
gcd=GCD(aNumerator,aDenominator) |
|||
if aNumerator<0 and aDenominator<0 then gcd=-1*gcd |
|||
bNumerator=aNumerator/gcd |
|||
bDenominator=aDenominator/gcd |
|||
b$=str$(bNumerator)+"/"+str$(bDenominator) |
|||
simplify$=b$ |
|||
end function |
|||
function reciprocal$(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
reciprocal$=str$(aDenominator)+"/"+str$(aNumerator) |
|||
end function |
|||
function equal(a$,b$) |
|||
if simplify$(a$)=simplify$(b$) then equal=1:else equal=0 |
|||
end function |
|||
function castToFraction$(a) |
|||
do |
|||
exp=exp+1 |
|||
a=a*10 |
|||
loop until a=int(a) |
|||
castToFraction$=simplify$(str$(a)+"/"+str$(10^exp)) |
|||
end function |
|||
function castToReal(a$) |
|||
aNumerator=val(word$(a$,1,"/")) |
|||
aDenominator=val(word$(a$,2,"/")) |
|||
castToReal=aNumerator/aDenominator |
|||
end function |
|||
function castToInt(a$) |
|||
castToInt=int(castToReal(a$)) |
|||
end function |
|||
function GCD(a,b) |
|||
if a=0 then |
|||
GCD=1 |
|||
else |
|||
if a>=b then |
|||
while b |
|||
c = a |
|||
a = b |
|||
b = c mod b |
|||
GCD = abs(a) |
|||
wend |
|||
else |
|||
GCD=GCD(b,a) |
|||
end if |
|||
end if |
|||
end function |
|||
</lang> |
|||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
http://www.rosettacode.org/wiki/M2000_Interpreter_rational_numbers |
http://www.rosettacode.org/wiki/M2000_Interpreter_rational_numbers |
||
Line 3,115: | Line 3,116: | ||
} |
} |
||
}</lang> |
}</lang> |
||
=={{header|Perl 6}}== |
|||
{{Works with|rakudo|2016.08}} |
|||
Perl 6 supports rational arithmetic natively. |
|||
<lang perl6>(2..2**19).hyper.map: -> $candidate { |
|||
my $sum = 1 / $candidate; |
|||
for 2 .. ceiling(sqrt($candidate)) -> $factor { |
|||
if $candidate %% $factor { |
|||
$sum += 1 / $factor + 1 / ($candidate / $factor); |
|||
} |
|||
} |
|||
if $sum.nude[1] == 1 { |
|||
say "Sum of reciprocal factors of $candidate = $sum exactly", ($sum == 1 ?? ", perfect!" !! "."); |
|||
} |
|||
}</lang> |
|||
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: |
|||
<lang perl6>for 1.0, 1.1, 1.2 ... 10 { .say }</lang> |
|||
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|Phix}}== |
=={{header|Phix}}== |
||
Line 3,588: | Line 3,571: | ||
-3/7<9/2 |
-3/7<9/2 |
||
9/2>-3/7 |
9/2>-3/7 |
||
-3/7=-3/7</pre> |
-3/7=-3/7</pre> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 3,647: | Line 3,630: | ||
2 |
2 |
||
</lang> |
</lang> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{Works with|rakudo|2016.08}} |
|||
Perl 6 supports rational arithmetic natively. |
|||
<lang perl6>(2..2**19).hyper.map: -> $candidate { |
|||
my $sum = 1 / $candidate; |
|||
for 2 .. ceiling(sqrt($candidate)) -> $factor { |
|||
if $candidate %% $factor { |
|||
$sum += 1 / $factor + 1 / ($candidate / $factor); |
|||
} |
|||
} |
|||
if $sum.nude[1] == 1 { |
|||
say "Sum of reciprocal factors of $candidate = $sum exactly", ($sum == 1 ?? ", perfect!" !! "."); |
|||
} |
|||
}</lang> |
|||
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: |
|||
<lang perl6>for 1.0, 1.1, 1.2 ... 10 { .say }</lang> |
|||
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}}== |
=={{header|REXX}}== |
||
Line 3,910: | Line 3,912: | ||
} |
} |
||
</lang> |
</lang> |
||
=={{header|Scheme}}== |
|||
Scheme has native rational numbers. |
|||
{{works with|Scheme|R5RS}} |
|||
<lang scheme>; simply prints all the perfect numbers |
|||
(do ((candidate 2 (+ candidate 1))) ((>= candidate (expt 2 19))) |
|||
(let ((sum (/ 1 candidate))) |
|||
(do ((factor 2 (+ factor 1))) ((>= factor (sqrt candidate))) |
|||
(if (= 0 (modulo candidate factor)) |
|||
(set! sum (+ sum (/ 1 factor) (/ factor candidate))))) |
|||
(if (= 1 (denominator sum)) |
|||
(begin (display candidate) (newline)))))</lang> |
|||
It might be implemented like this: |
|||
[insert implementation here] |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 3,987: | Line 3,974: | ||
} |
} |
||
}</lang> |
}</lang> |
||
=={{header|Scheme}}== |
|||
Scheme has native rational numbers. |
|||
{{works with|Scheme|R5RS}} |
|||
<lang scheme>; simply prints all the perfect numbers |
|||
(do ((candidate 2 (+ candidate 1))) ((>= candidate (expt 2 19))) |
|||
(let ((sum (/ 1 candidate))) |
|||
(do ((factor 2 (+ factor 1))) ((>= factor (sqrt candidate))) |
|||
(if (= 0 (modulo candidate factor)) |
|||
(set! sum (+ sum (/ 1 factor) (/ factor candidate))))) |
|||
(if (= 1 (denominator sum)) |
|||
(begin (display candidate) (newline)))))</lang> |
|||
It might be implemented like this: |
|||
[insert implementation here] |
|||
=={{header|Seed7}}== |
=={{header|Seed7}}== |