code 41004;
real procedure HYPERG(X, N, R, NN);
value X, N, R, NN; real X, N, R, NN;

begin integer I; real SUM, LAST, TERM; Boolean LEFT;
    if N < 0 ∨ N > NN ∨ N - ENTIER(N) ≠ 0 then
        STATAL3 ERROR(“HYPERG”, 2, N);
    if R <0 ∨ R > NN ∨ R - ENTIER(R) ≠ 0 then
        STATAL3 ERROR(“HYPERG”, 3, R);
    if NN - ENTIER(NN) ≠ 0 then
        STATAL3 ERROR(“HYPERG”, 4, NN);
    LEFT:= true;
    if N > NN / 2 then
    begin LEFT:= false; N:= NN - N; X:= R - X - 1 end;
    if R > NN / 2 then
    begin LEFT:= ¬ LEFT; R:= NN - R;
        X:= N - X - 1
    end;
    if N > R then begin I:= N; N:= R; R:= I end;
    if X <  0 then HYPERG:= if LEFT then 0 else 1
    else
    if X ≥ N then HYPERG:= if LEFT then 1 else 0
    else if NN > 105 then
    begin real BETA, TAU, CHI;
        TAU:= SQRT(R × N × (NN - N) × (NN - R) / NN) / NN;
        CHI:= (X + .5 - N × R / NN) / TAU;
        BETA:= (CHI × CHI + 2) / 12;
        X:= if R ≤ NN / 4 then
               2 × (SQRT((X + .5 + BETA)
               × (NN - R - N + X + .5 + BETA))
               - SQRT((N - X - .5 + BETA) ×
               (R - X - .5 + BETA))) /
               SQRT(NN + 1.5 - NN × NN / 2 / N / (NN - N))
                                else
               CHI + (CHI × CHI - 1) ×
               (2 × N - NN) × (NN - 2 × R)
               / 6 / TAU / NN / NN + CHI ×
               (1 - 3 × (NN - N) × N / NN / NN)
               / 48 / TAU / TAU;
        HYPERG:= PHI(if LEFT then X else -X)
    end else
    begin X:= ENTIER(X);
        TERM:= SUM:= HYPERGPROB(X, N, R, NN);
        if X > (N + 1) × (R + 1) / (NN + 2) then
        begin LEFT:= ¬ LEFT; SUM:= 0;
            for I:= X + 1, I + 1 while LAST < SUM do
            begin TERM:= TERM × (N - I + 1) × (R - I + 1)
                    / I / (NN - R - N + I);
                LAST:= SUM; SUM:= SUM + TERM
            end
        end else
        for I:= X, I - 1 while LAST < SUM do
        begin TERM:= TERM × I × (NN - N - R + I)
              / (N - I + 1) / (R - I + 1);
              LAST:= SUM; SUM:= SUM + TERM
        end;
        HYPERG:= if LEFT then SUM else 1 - SUM
    end
end HYPERG;
eop