The following function,   due to D. Hickerson,   is said to generate "Almost integers" by the

"Almost Integer" page of Wolfram MathWorld,   (December 31 2013).   (See formula numbered   51.)



The function is:           



h
(
n
)
=



n
!


2
(
ln
⁡

2


)

n
+
1







{\displaystyle h(n)={\operatorname {n} ! \over 2(\ln {2})^{n+1}}}





It is said to produce "almost integers" for   n   between   1   and   17.
The purpose of the task is to verify this assertion.

Assume that an "almost integer" has either a nine or a zero as its first digit after the decimal point of its decimal string representation



Task

Calculate all values of the function checking and stating which are "almost integers".

Note: Use extended/arbitrary precision numbers in your calculation if necessary to ensure you have adequate precision of results as for example:

               h(18) = 3385534663256845326.39...



with Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
 
procedure Almost_Integers is
 
   type Real is new Long_Long_Float;
 
   package Real_IO is
      new Ada.Text_IO.Float_IO (Real);
   package Integer_IO is
      new Ada.Text_IO.Integer_IO (Integer);
 
   function Faculty (N : in Long_Long_Integer) return Long_Long_Integer is
      (if N < 2 then N else N * Faculty (N - 1));
 
   function Hickerson (N : in Integer) return Real
   is
      package Math is
         new Ada.Numerics.Generic_Elementary_Functions (Real);
      LN2         : constant Real := Math.Log (2.0, Base => Ada.Numerics.E);
      Numerator   : constant Real := Real (Faculty (Long_Long_Integer (N)));
      Denominator : constant Real := 2.0 * LN2 ** (N + 1);
   begin
      return Numerator / Denominator;
   end Hickerson;
 
   function Is_Almost_Integer (N : Real) return Boolean is
      Image : String (1 .. 100);
   begin
      Real_IO.Put (Image, N, Exp => 0, Aft => 2);
 
      pragma Assert (Image (Image'Last - 2) = '.');
      case Image (Image'Last - 1) is
         when '0' | '9' =>  return True;
         when others    =>  return False;
      end case;
   end Is_Almost_Integer;
 
   use Ada.Text_IO;
   Placeholder : String := " n                         h(n)  almost";
   Image_N : String renames Placeholder ( 1 ..  2);
   Image_H : String renames Placeholder ( 4 .. 31);
   Image_A : String renames Placeholder (34 .. 39);
begin
   Put_Line (Placeholder);
   Image_N := (others => '-');
   Image_H := (others => '-');
   Image_A := (others => '-');
   Put_Line (Placeholder);
 
   for N in 1 .. 17 loop
      declare
         H : constant Real    := Hickerson (N);
         I : constant Boolean := Is_Almost_Integer (H);
      begin
         Integer_IO.Put (Image_N, N);
         Real_IO.Put (Image_H, H, Exp => 0, Aft => 4);
         Image_A := (if I then "TRUE " else "FALSE");
         Put_Line (Placeholder);
      end;
   end loop;
end Almost_Integers;