Bernoulli numbers: Difference between revisions
Content added Content deleted
(Added Quackery.) |
m (→{{header|REXX}}: elided a dead variable, added a note about calculation time.) |
||
Line 3,483: | Line 3,483: | ||
<br> |
<br> |
||
:::::::::::: where <big><big> <math> \binom kr</math> </big></big> is a binomial coefficient. <br> |
:::::::::::: where <big><big> <math> \binom kr</math> </big></big> is a binomial coefficient. <br> |
||
<lang rexx>/*REXX program calculates |
<lang rexx>/*REXX program calculates N number of Bernoulli numbers expressed as vulgar fractions.*/ |
||
parse arg N .; if N=='' | N=="," then N= 60 /*Not specified? Then use the default.*/ |
parse arg N .; if N=='' | N=="," then N= 60 /*Not specified? Then use the default.*/ |
||
numeric digits max(9, n*2) /*increase the decimal digits if needed*/ |
numeric digits max(9, n*2) /*increase the decimal digits if needed*/ |
||
w= max(length(N), 4); Nw= N + w + N % 4 /*used for aligning (output) fractions.*/ |
w= max(length(N), 4); Nw= N + w + N % 4 /*used for aligning (output) fractions.*/ |
||
say 'B(n)' center("Bernoulli |
say 'B(n)' center("Bernoulli numbers expressed as vulgar fractions", max(78-w, Nw) ) |
||
say copies('─',w) copies("─", max(78-w,Nw+2*w)) /*display 2nd line of title, separators*/ |
say copies('─',w) copies("─", max(78-w,Nw+2*w)) /*display 2nd line of title, separators*/ |
||
!.= |
!.= .; do #=0 to N /*process the numbers from 0 ──► N. */ |
||
b= bern(#); if b==0 then iterate /*calculate Bernoulli number, skip if 0*/ |
b= bern(#); if b==0 then iterate /*calculate Bernoulli number, skip if 0*/ |
||
indent= max(0, nW - pos('/', b) ) /*calculate the alignment (indentation)*/ |
indent= max(0, nW - pos('/', b) ) /*calculate the alignment (indentation)*/ |
||
say right(#, w) left('', indent) b /*display the indented Bernoulli number*/ |
say right(#, w) left('', indent) b /*display the indented Bernoulli number*/ |
||
end /*#*/ /* [↑] align the Bernoulli fractions. */ |
end /*#*/ /* [↑] align the Bernoulli fractions. */ |
||
exit |
exit 0 /*stick a fork in it, we're all done. */ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
bern: parse arg x; if x==0 then return '1/1' /*handle the special case of zero. */ |
bern: parse arg x; if x==0 then return '1/1' /*handle the special case of zero. */ |
||
Line 3,507: | Line 3,507: | ||
$lcm= LCM(sd, ad) /*use Least Common Denominator function*/ |
$lcm= LCM(sd, ad) /*use Least Common Denominator function*/ |
||
sn= $lcm % sd * sn; sd= $lcm /*calculate the current numerator. */ |
sn= $lcm % sd * sn; sd= $lcm /*calculate the current numerator. */ |
||
an= $lcm % ad * an |
an= $lcm % ad * an /* " " next " */ |
||
sn= sn + an /* " " current " */ |
sn= sn + an /* " " current " */ |
||
end /*k*/ /* [↑] calculate the SN/SD sequence.*/ |
end /*k*/ /* [↑] calculate the SN/SD sequence.*/ |
||
Line 3,520: | Line 3,520: | ||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
comb: procedure expose !.; parse arg x,y; if x==y then return 1 |
comb: procedure expose !.; parse arg x,y; if x==y then return 1 |
||
if !. |
if !.C.x.y\==. then return !.C.x.y /*combination computed before?*/ |
||
if x-y < y then y= x-y /*x-y < y? Then use a new Y.*/ |
if x-y < y then y= x-y /*x-y < y? Then use a new Y.*/ |
||
z= perm(x, y); do j=2 for y-1; z= z % j |
z= perm(x, y); do j=2 for y-1; z= z % j |
||
end /*j*/ |
end /*j*/ |
||
!. |
!.C.x.y= z; return z /*assign memoization & return.*/ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
GCD: procedure; parse arg x,y; x= abs(x) |
GCD: procedure; parse arg x,y; x= abs(x) |
||
do until y==0; parse value x//y y with y x; end; return x |
do until y==0; parse value x//y y with y x; end; return x |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
LCM: procedure; parse arg x,y |
LCM: procedure; parse arg x,y /*X=ABS(X); Y=ABS(Y) not needed for Bernoulli #s.*/ |
||
/*IF Y==0 THEN RETURN 0 " " " " " */ |
|||
$= x * y /*calculate part of the LCM here. */ |
|||
do until y==0; parse value x//y y with y x |
|||
end /*until*/ /* [↑] this is a short & fast GCD*/ |
|||
return $ % x /*divide the pre─calculated value.*/ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
perm: procedure expose !.; parse arg x,y; if !. |
perm: procedure expose !.; parse arg x,y; if !.P.x.y\==. then return !.P.x.y |
||
z= 1; do j=x-y+1 to x; z= z*j; end; !. |
z= 1; do j=x-y+1 to x; z= z*j; end; !.P.x.y= z; return z</lang> |
||
</lang> |
|||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre> |
<pre> |
||
B(n) |
B(n) Bernoulli numbers expressed as vulgar fractions |
||
──── ─────────────────────────────────────────────────────────────────────────────────────── |
──── ─────────────────────────────────────────────────────────────────────────────────────── |
||
0 1/1 |
0 1/1 |
||
Line 3,576: | Line 3,575: | ||
60 -1215233140483755572040304994079820246041491/56786730 |
60 -1215233140483755572040304994079820246041491/56786730 |
||
</pre> |
</pre> |
||
Output notes: This version of REXX can compute and display all values up to '''B<sub>110</sub>''' in sub─second. |
|||
<br><br> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |