Skip to content

Instantly share code, notes, and snippets.

@LindseyB
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LindseyB/7f6918fd87855468496c to your computer and use it in GitHub Desktop.
Save LindseyB/7f6918fd87855468496c to your computer and use it in GitHub Desktop.
-- Ada Lovelace is credited with writing the first program (one which calculated Bernoulli numbers)
-- Many years later the Ada programming language was created
--
-- This Ada uses the following algorithm for computing Bernoulli numbers
-- (http://en.wikipedia.org/wiki/Bernoulli_number#Algorithmic_description)
with Ada.Text_IO;
use Ada.Text_IO;
with Ada.Float_Text_IO; -- in Ada Float IO is treated differently from text IO, same goes for integers
use Ada.Float_Text_IO;
procedure Bernoulli is
type LargeArray is array(0..60) of Float; -- Define a type of LargeArray to hold allt he calculated values, I figured 60 would work (it wouldn't)
Result : LargeArray; -- This needs to be defined up here since it needs to happen before the begin (which is way down there)
function CalculateBernoulli (N: in Integer) return LargeArray is -- Functions are more like math functions, they need to return something - procedures don't
A : LargeArray; -- Like above need to be specified before we actually "begin" the function
Result : LargeArray;
begin
Result(0) := Float(1); -- B0 is 1, it doesn't make sense to loop on that so just assign it
for i in 1 .. N loop
for m in 1 .. i loop
A(m) := Float(1)/Float(m+1); -- There's no coercing of types, so both sides of the division need to "agree"
for j in reverse 1 .. m loop -- I was afraid I wouldn't be able to do a -1 step here, but reverse does the trick
A(j-1) := Float(j)*(A(j-1) - A(j)); -- Same as above, for this multiplication to happen they need to both be floats
end loop;
end loop;
Result(i) := A(0); -- Array accessing is done with () rather than []
end loop;
return Result;
end CalculateBernoulli;
begin
Result := CalculateBernoulli(60); -- This assignment has to happen, we can't just call a function and ignore the return
for i in 0 .. 60 loop -- I assumed we could hit B60, NOPE! Dies after B36
Put(i); -- I tried to find a cleaner way to do this
Ada.Text_IO.Put(", "); -- I really did
Put(Result(i)); -- I hate this
Ada.Text_IO.Put_Line(""); -- It's awful
end loop;
end Bernoulli;
0, 1.00000E+00
1, -5.00000E-01
2, -1.33333E+00
3, -2.33333E+00
4, -3.36667E+00
5, -4.36666E+00
6, -5.34285E+00
7, -6.34278E+00
8, -7.37498E+00
9, -8.35736E+00
10, -9.05751E+00
11, -7.48997E+00
12, 2.07991E+01
13, 3.96824E+02
14, 5.88580E+03
15, 9.72285E+04
16, 2.06362E+06
17, 6.17479E+07
18, 2.17479E+09
19, 7.44595E+10
20, 2.32011E+12
21, 6.52166E+13
22, 1.65596E+15
23, 3.75598E+16
24, 7.13392E+17
25, 7.51882E+18
26, -2.98290E+20
27, -3.29014E+22
28, -2.26170E+24
29, -1.39936E+26
30, -8.27503E+27
31, -4.73782E+29
32, -2.64143E+31
33, -1.44412E+33
34, -7.80963E+34
35, -4.21123E+36
36, -2.27520E+38
37, -Inf********
38, -Inf********
39, -Inf********
40, -Inf********
41, -Inf********
42, -Inf********
43, -Inf********
44, -Inf********
45, NaN*********
46, NaN*********
47, NaN*********
48, NaN*********
49, NaN*********
50, NaN*********
51, NaN*********
52, NaN*********
53, NaN*********
54, NaN*********
55, NaN*********
56, NaN*********
57, NaN*********
58, NaN*********
59, NaN*********
60, NaN*********
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment