Understanding the Synergy floating point API

The floating point API consists of single‑ and double‑operand routines that enable you to perform floating‑point calculations. Because DIBOL has no native floating‑point data type, we have implemented this support as routines, and data (the binary representation of the double result) is stored in a8 fields.

The floating‑point routines require that you follow these steps to perform floating‑point calculations:

1. Initialize your floating‑point a8 fields using the FP_FROM_NUM subroutine.
2. Perform the calculation using the appropriate FP_ routine.
3. Return the floating‑point a8 field to usable data using the FP_TO_NUM subroutine.

Sample program

The following example contains several of the FP_ routines.

subroutine calc_stats
;Returns mean and standard deviation for a set of numbers. This routine
;requires that the set's sum and sum of squares have been calculated and
;are passed as arguments. This eliminates the need for the caller to 
;build an array of the set -- handy for report writers etc.
    a_size   ,n                  ;Number of entries
    a_sum    ,n                  ;Sum of the entries
    a_sqs    ,n                  ;Sum of the squares
    a_mean   ,n                  ;Returned mean
    a_stdd   ,n                  ;Returned standard deviation
    a_sample ,n                  ;(Optional) flag. If TRUE, requests an 
                                ; unbiased standard deviation -- use this 
                                ; if estimating for the population based on 
                                ; the sample provided.
record
    fval    ,a8
    fn_1    ,a8                 ;Needed for nonbiased calculation
    fmean   ,a8
    fsum    ,a8
    fsqs    ,a8
    fstd    ,a8

proc
    if (a_size .lt. 2)
      begin
        if (a_size .eq. 1) then
          a_mean = a_sum
        else
          a_mean = 0
        a_stdd = 0
        xreturn
      end
    ;Get count, sum and sum of squares into floating–point
    ; variables for the standard deviation calculation:
    xcall fp_from_num(fval, %implied(a_size))
    xcall fp_from_num(fsum, %implied(a_sum))
    xcall fp_from_num(fsqs, %implied(a_sqs))
    if (^passed(a_sample) .and. a_sample) then
      begin             ;Does user want a sample–based estimate?
        xcall fp_from_num(fn_1, %implied(a_size – 1))
        xcall fp_div(fsqs, fsqs, fn_1)   ;Divide by n–1 instead of n 
        xcall fp_div(fmean, fsum, fval)  ; for samples (instead of  
        xcall fp_mul(fsum, fsum, fsum)   ; the whole population).
        xcall fp_mul(fval, fval, fn_1)   ; The n-1 denominator yields
        xcall fp_div(fsum, fsum, fval)   ; a larger estimate for small
      end                                ; samples.
    else
      begin             ;This is the whole "population"
        xcall fp_div(fsqs, fsqs, fval)
        xcall fp_div(fsum, fsum, fval)
        fmean = fsum
        xcall fp_mul(fsum, fsum, fsum)
      end
    xcall fp_to_num(fmean, a_mean)
    xcall fp_sub(fval, fsqs, fsum)
    xcall fp_sqrt(fval, fval)
    xcall fp_to_num(fval, a_stdd)
    xreturn
endsubroutine