Microsoft KB Archive/34958

From BetaArchive Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Calculating to Power of Fractional Exponent in COBOL; Roots

PSS ID Number: Q34958 Article last modified on 04-21-1993

2.00 2.10 2.20 3.00 3.00a | 3.00 3.00a MS-DOS | OS/2

The information in this article applies to:
- Microsoft COBOL for MS-DOS, versions 2.0, 2.1, 2.2, 3.0, and 3.0a - Microsoft COBOL for OS/2, versions 3.0 and 3.0a

Summary: Microsoft COBOL Versions 2.0, 2.1, 2.2, 3.0, and 3.0a provide an exponentiation operator () that accepts exponents that are whole numbers (such as 2.6 2). COBOL does not allow you to raise numbers to the power of a fractional exponent, such as 100 to the power of two-thirds (100 ** .666666). The base number can be fractional, but not the exponent. However, you can use a compute-and-average technique to approximate powers to a fractional exponent, as shown in the sample program below. For negative exponents like X ** -Y, the program runs faster if you modify it to calculate 1 divided by (X ** Y), which is equivalent. Warning: The sample program below may fail for small fractional roots, due to number format limitations. Please only use this information at your own risk.

More Information: Note that the square root of a number is the same as raising a number to the power of 0.5. The following is an example of how the “compute and average” algorithm works for the case of taking the square root: To take the square root of 36, do the following: 1. Divide 36 by 2, which gives 18. 2. Note that the square root of 36 is the same as 36 to the power of 0.5. This program arbitrarily makes a “first guess” of 2, the denominator of the exponent. Because 18 does not equal the “first guess” of 2, “average” then guesses as follows: (18 + 2) / 2 = 10 3. The new estimate is 10, and 18 is the old. Divide 36 by 10, which gives 3.6. 4. Because 3.6 does not equal 10, “average” then guesses as follows: (3.6 + 10) / 2 = 6.8 5. The new estimate is 6.8, and the old is 3.6. Divide 36 by 6.8, which gives 5.294. 6. Because 5.294 does not equal 6.8, “average” then guesses as follows: (6.8 + 5.294) / 2 = 6.047 This produces the latest estimate, 6.047. 7. As you can see, the estimate is rapidly approaching 6, which is the square root of 36. The above pattern is repeated until the difference between the old estimate and the new estimate is acceptably small. The following is a code example:

  * This Microsoft COBOL Version 2.0, 2.1, 2.2, or 3.0
  * program calculates roots or fractional exponents
  * using the "compute and average" method.
  *
  * This program calculates BASE to the power of
  * ( NUMERATOR / DENOMINATOR ) to an accuracy of plus or minus
  * the value stored in ACCURACY. The smaller you make the
  * value for ACCURACY, the longer the program will take.
  *
  * For negative exponents like BASE ** -N, modify the
  * program to calculate 1 / ( BASE ** N ), which is faster.
  *
  * The example below displays 21.544347, which is
  * approximately 100 ** (2/3), plus or minus .000005.
  *
  * Warning: Microsoft makes no guarantees that this technique
  * will work correctly for all roots. This is only an example
  * of a possible approach.
    IDENTIFICATION DIVISION.
    PROGRAM-ID. ROOTS.
    ENVIRONMENT DIVISION.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01 WORK-FIELDS.
        05 BASE              PIC 999       VALUE 100.
        05 NUMERATOR         PIC 9         VALUE 2.
        05 DENOMINATOR       PIC 9         VALUE 3.
  * The PIC clause for the TEMP-NUMBER must have room for
  * the number of digits in the BASE multiplied by the value
  * of the exponent's numerator. If not, inaccuracy will occur:
        05 TEMP-NUMBER       PIC 9(6)      VALUE 0.
        05 ESTIMATE          PIC 99V9(6)   VALUE 0.
        05 NEW-ESTIMATE      PIC 99V9(6)   VALUE 0.
        05 SHOW-ESTIMATE     PIC 99.9(6).
        05 AMOUNT-ERROR      PIC 99V9(6)   VALUE 1.
        05 ACCURACY          PIC 99V9(6)   VALUE 0.000005.
    PROCEDURE DIVISION.
    MAIN-CONTROL.
        COMPUTE TEMP-NUMBER = BASE ** NUMERATOR.
        COMPUTE ESTIMATE = TEMP-NUMBER / DENOMINATOR.
        PERFORM CALCULATE-ROOT
           UNTIL AMOUNT-ERROR < ACCURACY.
        MOVE ESTIMATE TO SHOW-ESTIMATE.
        DISPLAY SHOW-ESTIMATE.
        STOP RUN.
    CALCULATE-ROOT.
        COMPUTE ESTIMATE = (ESTIMATE + NEW-ESTIMATE) / 2.
        COMPUTE NEW-ESTIMATE =
             TEMP-NUMBER / ( ESTIMATE ** ( DENOMINATOR - 1 ) ).
        COMPUTE AMOUNT-ERROR = ESTIMATE - NEW-ESTIMATE.

Additional reference words: 2.00 2.10 2.20 3.00 3.00a Copyright Microsoft Corporation 1993.