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
