Hickerson series of almost integers: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Perl 6}}: format output)
Line 80: Line 80:
for 0 .. 17 -> $n {
for 0 .. 17 -> $n {
my $h = h($n);
my $h = h($n);
printf "h(%2d) ≈ %26.6f is {$h ~~ AlmostInt ?? "" !! "NOT "} almost integer\n", $n, $h;
printf "h(%2d) ≈ %26.6f is {$h ~~ AlmostInt ?? "" !! "NOT "}almost integer\n", $n, $h;
}</lang>
}</lang>
{{out}}
{{out}}
<pre>h( 0) ≈ 0.721348 is NOT almost integer
<pre>h( 0) ≈ 0.721348 is NOT almost integer
h( 1) ≈ 1.040684 is almost integer
h( 1) ≈ 1.040684 is almost integer
h( 2) ≈ 3.002781 is almost integer
h( 2) ≈ 3.002781 is almost integer
h( 3) ≈ 12.996291 is almost integer
h( 3) ≈ 12.996291 is almost integer
h( 4) ≈ 74.998735 is almost integer
h( 4) ≈ 74.998735 is almost integer
h( 5) ≈ 541.001519 is almost integer
h( 5) ≈ 541.001519 is almost integer
h( 6) ≈ 4683.001247 is almost integer
h( 6) ≈ 4683.001247 is almost integer
h( 7) ≈ 47292.998731 is almost integer
h( 7) ≈ 47292.998731 is almost integer
h( 8) ≈ 545834.997907 is almost integer
h( 8) ≈ 545834.997907 is almost integer
h( 9) ≈ 7087261.001623 is almost integer
h( 9) ≈ 7087261.001623 is almost integer
h(10) ≈ 102247563.005271 is almost integer
h(10) ≈ 102247563.005271 is almost integer
h(11) ≈ 1622632572.997550 is almost integer
h(11) ≈ 1622632572.997550 is almost integer
h(12) ≈ 28091567594.981575 is almost integer
h(12) ≈ 28091567594.981575 is almost integer
h(13) ≈ 526858348381.001282 is almost integer
h(13) ≈ 526858348381.001282 is almost integer
h(14) ≈ 10641342970443.085938 is almost integer
h(14) ≈ 10641342970443.085938 is almost integer
h(15) ≈ 230283190977853.062500 is almost integer
h(15) ≈ 230283190977853.062500 is almost integer
h(16) ≈ 5315654681981354.000000 is NOT almost integer
h(16) ≈ 5315654681981354.000000 is NOT almost integer
h(17) ≈ 130370767029135888.000000 is NOT almost integer</pre>
h(17) ≈ 130370767029135888.000000 is NOT almost integer</pre>


=={{header|Python}}==
=={{header|Python}}==

Revision as of 15:45, 3 January 2014

Hickerson series of almost integers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The following function, due to D Hickerson is said to generate "Almost integers" by the "Almost Integer" page of Wolfram Mathworld. (December 31 2013).

The function is:

The function is said to produce "almost integers" for n in the given range.

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

The task is to 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...

COBOL

Works with: GNU Cobol version 2.0

<lang cobol> >>SOURCE FREE IDENTIFICATION DIVISION. PROGRAM-ID. hickerson-series.

ENVIRONMENT DIVISION. CONFIGURATION SECTION. REPOSITORY.

   FUNCTION ALL INTRINSIC
   .

DATA DIVISION. WORKING-STORAGE SECTION. 01 n PIC 99 COMP.

01 h PIC Z(19)9.9(10).

01 First-Decimal-Digit-Pos CONSTANT 22.

PROCEDURE DIVISION.

   PERFORM VARYING n FROM 0 BY 1 UNTIL n > 17
       COMPUTE h = FACTORIAL(n) / (2 * LOG(2) ** (n + 1))
       DISPLAY "h(" n ") = " h " which is " NO ADVANCING
       IF h (First-Decimal-Digit-Pos:1) = "0" OR "9"
           DISPLAY "an almost integer."
       ELSE
           DISPLAY "not an almost integer."
       END-IF
   END-PERFORM
   .

END PROGRAM hickerson-series.</lang>

Output:
h(00) =                    0.7213475204 which is not an almost integer.
h(01) =                    1.0406844905 which is an almost integer.
h(02) =                    3.0027807071 which is an almost integer.
h(03) =                   12.9962905052 which is an almost integer.
h(04) =                   74.9987354476 which is an almost integer.
h(05) =                  541.0015185164 which is an almost integer.
h(06) =                 4683.0012472622 which is an almost integer.
h(07) =                47292.9987313146 which is an almost integer.
h(08) =               545834.9979074851 which is an almost integer.
h(09) =              7087261.0016228991 which is an almost integer.
h(10) =            102247563.0052710420 which is an almost integer.
h(11) =           1622632572.9975500498 which is an almost integer.
h(12) =          28091567594.9815724407 which is an almost integer.
h(13) =         526858348381.0012482861 which is an almost integer.
h(14) =       10641342970443.0845319270 which is an almost integer.
h(15) =      230283190977853.0374360391 which is an almost integer.
h(16) =     5315654681981354.5130767434 which is not an almost integer.
h(17) =   130370767029135900.4579853491 which is not an almost integer.

Perl 6

We'll use FatRat values, and a series for an approximation of ln(2).

<lang Perl 6>constant ln2 = [\+] map { 1.FatRat / 2**$_ / $_ }, 1 .. *;

subset AlmostInt of FatRat where -> $x { abs($x - $x.round) < .1 } sub h($n) returns FatRat { ([*] 2 .. $n) / (2*ln2[100]**($n+1)) }

for 0 .. 17 -> $n {

   my $h = h($n);
   printf "h(%2d) ≈ %26.6f is {$h ~~ AlmostInt ?? "" !! "NOT "}almost integer\n", $n, $h;

}</lang>

Output:
h( 0) ≈                   0.721348 is NOT almost integer
h( 1) ≈                   1.040684 is almost integer
h( 2) ≈                   3.002781 is almost integer
h( 3) ≈                  12.996291 is almost integer
h( 4) ≈                  74.998735 is almost integer
h( 5) ≈                 541.001519 is almost integer
h( 6) ≈                4683.001247 is almost integer
h( 7) ≈               47292.998731 is almost integer
h( 8) ≈              545834.997907 is almost integer
h( 9) ≈             7087261.001623 is almost integer
h(10) ≈           102247563.005271 is almost integer
h(11) ≈          1622632572.997550 is almost integer
h(12) ≈         28091567594.981575 is almost integer
h(13) ≈        526858348381.001282 is almost integer
h(14) ≈      10641342970443.085938 is almost integer
h(15) ≈     230283190977853.062500 is almost integer
h(16) ≈    5315654681981354.000000 is NOT almost integer
h(17) ≈  130370767029135888.000000 is NOT almost integer

Python

This uses Pythons decimal module of fixed precision decimal floating point calculations.

<lang python>from decimal import Decimal import math

def h(n):

   'Simple, reduced precision calculation'
   return math.factorial(n) / (2 * math.log(2) ** (n + 1))
   

def h2(n):

   'Extended precision Hickerson function'
   return Decimal(math.factorial(n)) / (2 * Decimal(2).ln() ** (n + 1))

for n in range(18):

   x = h2(n)
   norm = str(x.normalize())
   almostinteger = (' Nearly integer' 
                    if 'E' not in norm and ('.0' in norm or '.9' in norm) 
                    else ' NOT nearly integer!')
   print('n:%2i h:%s%s' % (n, norm, almostinteger))</lang>
Output:
n: 0 h:0.7213475204444817036799623405 NOT nearly integer!
n: 1 h:1.040684490502803898934790802 Nearly integer
n: 2 h:3.002780707156905443499767406 Nearly integer
n: 3 h:12.99629050527696646222488454 Nearly integer
n: 4 h:74.99873544766160012763455035 Nearly integer
n: 5 h:541.0015185164235075692027746 Nearly integer
n: 6 h:4683.001247262257437180467151 Nearly integer
n: 7 h:47292.99873131462390482283547 Nearly integer
n: 8 h:545834.9979074851670672910395 Nearly integer
n: 9 h:7087261.001622899120979187513 Nearly integer
n:10 h:102247563.0052710420110883885 Nearly integer
n:11 h:1622632572.997550049852874859 Nearly integer
n:12 h:28091567594.98157244071518915 Nearly integer
n:13 h:526858348381.0012482861804887 Nearly integer
n:14 h:10641342970443.08453192709506 Nearly integer
n:15 h:230283190977853.0374360391257 Nearly integer
n:16 h:5315654681981354.513076743451 NOT nearly integer!
n:17 h:130370767029135900.4579853491 NOT nearly integer!

The range for should be reduced to be for this definition of almost integer.

Ruby

Using the BigDecimal standard library: <lang ruby> require "bigdecimal"

LN2 = BigMath::log(2,16) #Use LN2 = Math::log(2) to see the difference with floats FACTORIALS = Hash.new{|h,k,v| h[k]=k * h[k-1]} FACTORIALS[0] = 1

def hickerson(n)

 FACTORIALS[n] / (2 * LN2 ** (n+1))

end

def nearly_int?(n)

 int = n.round
 n.between?(int - 0.1, int + 0.1)

end

1.upto(17) do |n|

 h = hickerson(n)
 str = nearly_int?(h) ? "nearly integer" : "NOT nearly integer"
 puts "n:%3i h: %s\t%s" % [n, h.to_s('F')[0,25], str] #increase the 25 to print more digits, there are 856 of them

end

</lang>

Output:
n:  1 h: 1.04068449050280389893479	nearly integer
n:  2 h: 3.00278070715690544349976	nearly integer
n:  3 h: 12.9962905052769664622248	nearly integer
n:  4 h: 74.9987354476616001276345	nearly integer
n:  5 h: 541.001518516423507569202	nearly integer
n:  6 h: 4683.00124726225743718046	nearly integer
n:  7 h: 47292.9987313146239048228	nearly integer
n:  8 h: 545834.997907485167067291	nearly integer
n:  9 h: 7087261.00162289912097918	nearly integer
n: 10 h: 102247563.005271042011088	nearly integer
n: 11 h: 1622632572.99755004985287	nearly integer
n: 12 h: 28091567594.9815724407151	nearly integer
n: 13 h: 526858348381.001248286180	nearly integer
n: 14 h: 10641342970443.0845319270	nearly integer
n: 15 h: 230283190977853.037436039	nearly integer
n: 16 h: 5315654681981354.51307674	NOT nearly integer
n: 17 h: 130370767029135900.457985	NOT nearly integer