DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: B T

⟦ac6e936cb⟧ TextFile

    Length: 5066 (0x13ca)
    Types: TextFile
    Names: »B«

Derivation

└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
    └─⟦5cb1d1d7f⟧ »DATA« 
        └─⟦3b1ee7bd8⟧ 
            └─⟦this⟧ 

TextFile

with System;
package body Natural_Package is
    --==================================================================
    -- This package provides the natural log function that returns the
    -- log base e of a positive, floating-point number.
    --
    -- This package attempts to do some minimal numerical analysis in
    -- order to compute the result to the requested accuracy.  The
    -- expression for the termination of the loop comes from the book
    -- "Portability and Style in Ada" by Nissen and Wallis.
    --
    -- The method used to compute the natural log is based on the
    -- Taylor series expansion for ln x:
    --    ln(x) = 2 * {     (x-1)/(x+1)     +
    --                  1/3[(x-1)/(x+1)]**3 +
    --                  1/5[(x-1)/(x+1)]**5 + ...}
    --
    -- The accuracy of the calcuation is improved by first by using the
    -- mathmatical property that ln(e**x) = x*ln(e) = x.  In this case,
    -- the number being passed into the log function is repeatedly
    -- divided by e to find out the highest power of e that is a factor
    -- of the argument.  This power then becomes the characteristic of
    -- the log function.  The remainder of the log function is then
    -- put into the Taylor series and it's value calculated.  This is
    -- then the mantissa of the log of the argument.
    --
    -- The exception Negative_Log is raised if the argument to the
    -- log function is <= 0.0
    --
    -- The exception Value_To_Large is raised if the argument to the
    -- log function causes an overflow to occur. (i.e. if Numeric_Error
    -- or Constraint_Error is raised).
    --
    -- Version 2.0 December 5, 1985
    --
    -- Written by Brad Balfour with help and suggestions from
    -- Ed Berard, Johan Margono and Gary Russell
    --==================================================================


    function Log (Of_Value : in Argument) return Return_Value is
        --===============================================================
        --
        -- calculates the natural log of a positive floating point number
        -- as described above
        --
        -- Version 2.0 December 5, 1985
        --
        -- Written by Brad Balfour with help and suggestions from
        -- Ed Berard, Johan Margono and Gary Russell
        --===============================================================


        type Accurate_Float is digits System.Max_Digits;
        -- a very accurate floating point number used for
        -- all internal calculations

        Copy_Of_Value : Accurate_Float := Accurate_Float (Of_Value);
        -- a copy of the argument that may be changed

        Single_Term : Accurate_Float := 0.0;
        -- holds a single term in the series

        Characteristic : Accurate_Float := 0.0;
        -- holds the characteritic of the log value

        New_Log_Value : Accurate_Float := 0.0;
        -- accumulates the new log value mantissa

        type Exponent is range 1 .. System.Max_Int;
        -- this holds the exponent for the Taylor series

        Current_Exponent : Exponent := 1;
        -- holds the exponent for the current term in the series

        Fraction : Accurate_Float;
        -- contains the expression used in the Taylor series

        E : constant := 2.718_281_828_459_045_235_360_287; --...
        -- the natural logarithm base


    begin
        -- Log

        if Of_Value <= 0.0 then

            raise Negative_Log;

        else
            -- ok to compute the log

            Find_Characteristic:
                while Copy_Of_Value > E loop

                    Copy_Of_Value := Copy_Of_Value / E;
                    Characteristic := Characteristic + 1.0;
                    -- add 1 to the characteristic

                end loop Find_Characteristic;

            --
            -- Now 0 <= Copy_Of_Value < E
            --

            if Copy_Of_Value /= 0.0 then
                -- was not an exact multiple of E.  calc. mantissa

                Fraction := (Copy_Of_Value - 1.0) / (Copy_Of_Value + 1.0);
                -- used in the Taylor series

                Compute_Mantissa:
                    loop
                        -- must do at least one term to know if it
                        -- is accurate

                        Single_Term := (Fraction **
                                        Integer (Current_Exponent)) /
                                       Accurate_Float (Current_Exponent);

                        exit Compute_Mantissa when
                           Single_Term <= (New_Log_Value *
                                           Accurate_Float'Epsilon);

                        New_Log_Value := New_Log_Value + Single_Term;
                        Current_Exponent := Current_Exponent + 1;

                    end loop Compute_Mantissa;

            end if;

            return Return_Value ((2.0 * New_Log_Value) + Characteristic);

        end if;


    exception
        when Numeric_Error | Constraint_Error =>
            raise Value_Too_Large;
    end Log;

end Natural_Package;