Troubleshooting
Problem
The implementation of floating-point numbers on the IBM i operating system for languages supporting such data types (RPG, COBOL, C, Java) follows the ANSI/IEEE standard 754-1985.
Resolving The Problem
The implementation of floating-point numbers on the IBM i operating system for languages supporting such data types (RPG, COBOL, C, Java) follows the ANSI/IEEE standard 754-1985. More specifically, single- and double-precision floating-point types are supported, while double-extended/quadruple precision is not (standard 754-1985 has a provision for this precision level). The following table shows a breakdown of these types by length of exponent and mantissa:
The following table shows the smallest and largest allowable absolute values for each precision level:
The following table shows comparative definitions of floating-point fields in different programming languages:
The next several sections present additional details on how different languages and utilities handle or support floating-point numbers.
ILE RPG IV
The floating-point data type (type F) in ILE RPG IV allows application programmers to manipulate numeric values outside the range of ordinary numeric fields such as zoned or packed. (Note that in RPG the maximum number of digits for these types is 30 and there is no exponent of 10). Floating-point fields may be 4 or 8 bytes long (for example, single- or double-precision, respectively). The following are examples of single- and double-precision variables declared in D specifications:
* single precision
D var1 S 4F
* double precision
D var2 S 8F
All type F fields have decimal places, even though these are not explicitly defined as in the case of zoned or packed numeric fields. Floating-point fields may not be used as indices in loops or arrays.
Assignments to floating-point fields may only be made via the EVAL opcode, as MOVE and MOVEL do not support this data type.
Type F fields are allowed as key fields in ILE RPG IV, for example, as search arguments in opcodes SETLL, CHAIN, and so on. However, using such fields as keys is likely not advisable -- floating-point numbers tend to be approximate, whereas key matching is exact. Consider, for example, the CHAIN opcode. It can locate a given record based on a type F search argument, but only if there is an exact digit-for-digit match between the search argument and a record's key value. For example, if a record contains a key value of 0.9998, then search arguments 0.9997 or 0.9999 will not produce a hit even if the user can accept a search tolerance greater than or equal to 10 ** -4. A sample program at the end of this document demonstrates how to implement searches with approximate hits through embedded SQL.
ILE COBOL
ILE COBOL supports single- and double-precision types, whose usage is COMP-1 and COMP-2, respectively.
Example:
05 VAR1 USAGE COMP-1.
05 VAR2 USAGE COMP-2.
These data types enable programs to store much larger numbers than in the case of COMP-3 (packed decimal, limited to an 18-digit maximum) or COMP-4 (binary integer, limited to an 18-digit maximum).
ILE C
In ILE C, single-precision variables are of type "float", while double-precision ones are of type "double"; for example:
/* single precision */
float var1;
/* double precision */
double var2;
CL (ILE/OPM)
CL provides no support for floating-point values or variables, and is unable to perform file I/O operations on database files or display files using floating-point data. Floating-point parameters may be passed from one HLL (High-Level Language) program or module to another, via an intermediate CL program or module. CL can receive and resend such parameters, but they have to be declared as:
DCL VAR(parameter_name) TYPE(*CHAR) LEN(4)
for single-precision parameters or as:
DCL VAR(parameter_name) TYPE(*CHAR) LEN(8)
for double-precision parameters.
DFU
DFU does not support floating-point fields as indicated in appendix A of the DFU manual. Attempting to access a file containing floating-point fields via DFU results in an error message DFU0415.
RUNQRY
Files containing floating-point fields can be viewed using the following CL command:
RUNQRY () filename
DSPF
When running DSPF on a file containing floating-point fields, the contents of such fields are displayed as special characters. Pressing function key <F10> will cause the floating-point data to be displayed in hex format.
DSPPFM
When running DSPPFM on a file containing floating-point fields, the contents of such fields are displayed as "unprintable" characters. Pressing function key <F10> will cause the floating-point data to be displayed in hex format.
SQL
STRSQL (interactive SQL interpreter) may be used to display, insert or modify floating-point data in a file. This is especially useful given the lack of such functionality in DFU.
SQL statements may also be embedded in high-level language applications to handle floating-point numbers.
Files, DDS Keywords
Within DDS, floating-point fields are denoted by type F. The number of decimal positions is stated explicitly (unlike floating-point fields defined in ILE RPG programs) and can run from 1 to 9 for single precision, or from 1 to 17 for double precision. Double-precision fields are coded with keyword FLTPCN(*DOUBLE); fields of type F without this keyword default to single precision.
Floating-point fields may appear in physical, display and printer files. Such fields may also be declared as keys in a database file's DDS. This will compile, but the key will only match exact search arguments in programs; this is not much use in practice because floating-point values are most often approximations. DDS keyword FLTFIXDEC can be used in display and printer files to output the contents of a floating-point field in fixed-point decimal notation.
Floating-Point Numbers on the Command Line
When calling from the command line a program expecting one or more floating-point parameters, the user should make sure to enter such parameters in the appropriate format: conversion from other numeric formats (for example, integer, real number without exponent) does not occur. Consider the following ILE RPG program:
When called from the command line, the program needs a parameter entered according to the following syntax:
(X. or SX. or .Y or S.Y or X.Y or SX.Y) and E and (SZ or Z)
X digits to the left of the decimal point
. decimal point
Y digits to the right of the decimal point
E letter 'e' or 'E' (denotes beginning of exponent of 10)
S sign ('+' or '-'); when omitted defaults to '+'
Z digits for exponent of 10
Following are some examples of valid floating-point literals on the command line:
1.E0
1.E+0
1.E-0
+1.E0
+1.E+0
+1.E-0
-1.E0
-1.E+0
-1.E-0
.5E1
.5E+1
.5E-1
+.5E1
+.5E+1
+.5E-1
-.5E1
-.5E+1
-.5E-1
1.2E2
1.2E+2
1.2E-2
+1.2E2
+1.2E+2
+1.2E-2
-1.2E2
-1.2E+2
-1.2E-2
ILE RPG Source FLOAT4:
| Precision | Total Length (bits) | Sign (bits) | Exponent (bits) | Mantissa (bits) |
| Single | 32 | 1 | 8 | 23 |
| Double | 64 | 1 | 11 | 52 |
| Double-extended/ quadruple (not supported on OS/400) |
128 | 1 | 15 | 112 |
The following table shows the smallest and largest allowable absolute values for each precision level:
| Precision | Minimum Allowable Absolute Value | Maximum Allowable Absolute Value |
| Single | 2 ** -126 ( ≈ 1.1754944E-38) |
2 ** +128 ( ≈ 3.4028235E+38) |
| Double | 2 ** -1022 ( ≈ 2.2250738585072013E-308) |
2 ** +1024 ( ≈ 1.797693134862315E+308) |
| Double-extended (quadruple) |
2 ** -16382 (3.3621031431120935062626778173218E-4932) |
2 ** +16384 (1.189731495357231765085759326628E+4932) |
The following table shows comparative definitions of floating-point fields in different programming languages:
| Precision | DDS | ILE RPG | ILE COBOL | ILE C |
| Single defined in |
1F - 9F (1 up to 9 decimal mantissa digits) field definition with field-level keyword: FLTPCN(*SINGLE) |
4F (4-byte floating-point) D specifications |
COMP-1 USAGE clause of computational items |
float global or local variable declarations |
| Double defined in |
1F - 17F (1 up to 17 decimal mantissa digits) field definition with field-level keyword: FLTPCN(*DOUBLE) |
8F (8-byte floating-point) D specifications |
COMP-2 USAGE clause of computational items |
double global or local variable declarations |
The next several sections present additional details on how different languages and utilities handle or support floating-point numbers.
ILE RPG IV
The floating-point data type (type F) in ILE RPG IV allows application programmers to manipulate numeric values outside the range of ordinary numeric fields such as zoned or packed. (Note that in RPG the maximum number of digits for these types is 30 and there is no exponent of 10). Floating-point fields may be 4 or 8 bytes long (for example, single- or double-precision, respectively). The following are examples of single- and double-precision variables declared in D specifications:
* single precision
D var1 S 4F
* double precision
D var2 S 8F
All type F fields have decimal places, even though these are not explicitly defined as in the case of zoned or packed numeric fields. Floating-point fields may not be used as indices in loops or arrays.
Assignments to floating-point fields may only be made via the EVAL opcode, as MOVE and MOVEL do not support this data type.
Type F fields are allowed as key fields in ILE RPG IV, for example, as search arguments in opcodes SETLL, CHAIN, and so on. However, using such fields as keys is likely not advisable -- floating-point numbers tend to be approximate, whereas key matching is exact. Consider, for example, the CHAIN opcode. It can locate a given record based on a type F search argument, but only if there is an exact digit-for-digit match between the search argument and a record's key value. For example, if a record contains a key value of 0.9998, then search arguments 0.9997 or 0.9999 will not produce a hit even if the user can accept a search tolerance greater than or equal to 10 ** -4. A sample program at the end of this document demonstrates how to implement searches with approximate hits through embedded SQL.
ILE COBOL
ILE COBOL supports single- and double-precision types, whose usage is COMP-1 and COMP-2, respectively.
Example:
05 VAR1 USAGE COMP-1.
05 VAR2 USAGE COMP-2.
These data types enable programs to store much larger numbers than in the case of COMP-3 (packed decimal, limited to an 18-digit maximum) or COMP-4 (binary integer, limited to an 18-digit maximum).
ILE C
In ILE C, single-precision variables are of type "float", while double-precision ones are of type "double"; for example:
/* single precision */
float var1;
/* double precision */
double var2;
CL (ILE/OPM)
CL provides no support for floating-point values or variables, and is unable to perform file I/O operations on database files or display files using floating-point data. Floating-point parameters may be passed from one HLL (High-Level Language) program or module to another, via an intermediate CL program or module. CL can receive and resend such parameters, but they have to be declared as:
DCL VAR(parameter_name) TYPE(*CHAR) LEN(4)
for single-precision parameters or as:
DCL VAR(parameter_name) TYPE(*CHAR) LEN(8)
for double-precision parameters.
DFU
DFU does not support floating-point fields as indicated in appendix A of the DFU manual. Attempting to access a file containing floating-point fields via DFU results in an error message DFU0415.
RUNQRY
Files containing floating-point fields can be viewed using the following CL command:
RUNQRY () filename
DSPF
When running DSPF on a file containing floating-point fields, the contents of such fields are displayed as special characters. Pressing function key <F10> will cause the floating-point data to be displayed in hex format.
DSPPFM
When running DSPPFM on a file containing floating-point fields, the contents of such fields are displayed as "unprintable" characters. Pressing function key <F10> will cause the floating-point data to be displayed in hex format.
SQL
STRSQL (interactive SQL interpreter) may be used to display, insert or modify floating-point data in a file. This is especially useful given the lack of such functionality in DFU.
SQL statements may also be embedded in high-level language applications to handle floating-point numbers.
Files, DDS Keywords
Within DDS, floating-point fields are denoted by type F. The number of decimal positions is stated explicitly (unlike floating-point fields defined in ILE RPG programs) and can run from 1 to 9 for single precision, or from 1 to 17 for double precision. Double-precision fields are coded with keyword FLTPCN(*DOUBLE); fields of type F without this keyword default to single precision.
Floating-point fields may appear in physical, display and printer files. Such fields may also be declared as keys in a database file's DDS. This will compile, but the key will only match exact search arguments in programs; this is not much use in practice because floating-point values are most often approximations. DDS keyword FLTFIXDEC can be used in display and printer files to output the contents of a floating-point field in fixed-point decimal notation.
Floating-Point Numbers on the Command Line
When calling from the command line a program expecting one or more floating-point parameters, the user should make sure to enter such parameters in the appropriate format: conversion from other numeric formats (for example, integer, real number without exponent) does not occur. Consider the following ILE RPG program:
**FREE
// Prototype for FLOAT1
Dcl-Pr Pgm_FLOAT1 ExtPgm('FLOAT1');
argument Float(8);
End-Pr;
// Procedure interface for FLOAT1
Dcl-Pi Pgm_FLOAT1;
argument Float(8);
End-Pi;
Dsply '' '' argument;
*inlr = *on;
When called from the command line, the program needs a parameter entered according to the following syntax:
(X. or SX. or .Y or S.Y or X.Y or SX.Y) and E and (SZ or Z)
X digits to the left of the decimal point
. decimal point
Y digits to the right of the decimal point
E letter 'e' or 'E' (denotes beginning of exponent of 10)
S sign ('+' or '-'); when omitted defaults to '+'
Z digits for exponent of 10
Following are some examples of valid floating-point literals on the command line:
1.E0
1.E+0
1.E-0
+1.E0
+1.E+0
+1.E-0
-1.E0
-1.E+0
-1.E-0
.5E1
.5E+1
.5E-1
+.5E1
+.5E+1
+.5E-1
-.5E1
-.5E+1
-.5E-1
1.2E2
1.2E+2
1.2E-2
+1.2E2
+1.2E+2
+1.2E-2
-1.2E2
-1.2E+2
-1.2E-2
Type command, press Enter.
===> call float2 123.E0
===> call float2 123.E0
DSPLY +1.230000000000000E+002
? *N
DSPLY +1.230000000000000E+002
? *N
Example Combining DDS, ILE RPG, SQL
The following sample program illustrates floating-point definition and handling in DDS, ILE RPG and embedded SQL statements. The application reads from a file records containing floating-point values, which are within user-specified lower and upper bounds. The application then sums all such values and displays the mean of all values selected.
DDS for Physical File FLOATPF
? *N
DSPLY +1.230000000000000E+002
? *N
Example Combining DDS, ILE RPG, SQL
The following sample program illustrates floating-point definition and handling in DDS, ILE RPG and embedded SQL statements. The application reads from a file records containing floating-point values, which are within user-specified lower and upper bounds. The application then sums all such values and displays the mean of all values selected.
DDS for Physical File FLOATPF
A* This record format consists of one double-precision, floating-point
A* field. Type F denotes the field is floating-point, while the FLTPCN
A* keyword determines the field's precision: *SINGLE for a 4-byte field,
A* *DOUBLE for an 8-byte field.
A*
A R FLOATREC
A FLD1 17F 7B FLTPCN(*DOUBLE)
DDS for Display File FLOATDSPF1
A* This display file works in conjunction with the ILE RPG program to
A* select floating-point values from a DB file, add them up and calculate
A* their mean.
A*
A DSPSIZ(24 80 *DS3)
A*
A* The INVITE keyword is needed to display intermediate results.
A*
A INVITE
A R DSPFREC
A*
A* User-specified lower and upper bounds for record retrieval.
A*
A 5 10'Lower Bound:'
A LT_OR_EQ 17F 7B 7 10FLTPCN(*DOUBLE)
A FLTFIXDEC
A 5 50'Upper Bound:'
A GT_OR_EQ 17F 7B 7 50FLTPCN(*DOUBLE)
A FLTFIXDEC
A*
A* Value of current record.
A*
A N99 10 10'Current Value:'
A 99 10 10'Last Value:'
A CUR_VAL 17F 7O 12 10FLTPCN(*DOUBLE)
A FLTFIXDEC
A*
A* Running total for all records retrieved.
A*
A N99 10 50'Subtotal:'
A 99 10 50'Total:'
A CUR_SUM 17F 7O 12 50FLTPCN(*DOUBLE)
A FLTFIXDEC
A*
A* Number of records processed.
A*
A N99 15 10'Number of Records Processed:'
A 99 15 10'Total Number of Records Processed:'
A CUR_N 17F 7O 17 10FLTPCN(*DOUBLE)
A FLTFIXDEC
A*
A* Running mean of record values retrieved.
A*
A 15 50'Mean:'
A CUR_MEAN 17F 7O 17 50FLTPCN(*DOUBLE)
A FLTFIXDEC
ILE RPG Source FLOAT4:
**FREE
//*********************************************************************************************
// This program computes a running mean of floating-point values from DB file records.
// The program first prompts the user for lower and upper bounds of numbers to be processed,
// then retrieves all records within those bounds and processes them one by one.
// The purpose of this program is primarily to demonstrate how approximate floating-point
// values can be retrieved via SQL, given some tolerance value: this is important because
// RPG opcodes such as CHAIN only match exact values, and floating-point numbers are most
// often approximate. For example, we may want to retrieve all records with a value of
// 1 +/- 10 ** -3, i.e. 0.999 <= value <= 1.001: this is easily achieved using the technique
// shown in this program.
//
// File containing floating-point values.
//
Dcl-F floatpf ;
//
// Display file for intermediate and final results.
//
Dcl-F floatdspf1 WORKSTN;
//
// Prototype for QCMDEXC. This is used to issue a DLYJOB command, so the user can read
// intermediate results on the screen.
//
Dcl-Pr System_Command EXTPGM('QCMDEXC');
Pr_Cmd Char(80);
Pr_Cmd_Length Packed(15:5);
End-Pr;
//
// Lower and upper bounds for floating-point number selection.
//
Dcl-S lower_bound Float(8) INZ(0);
Dcl-S upper_bound Float(8) INZ(0);
Dcl-S total Float(8) INZ(0); // Running total
Dcl-S partial Float(8) INZ(0); //Value of current r
Dcl-S n Float(8) INZ(0); // Numof recs so far
Dcl-S mean Float(8) INZ(0); // Running mean
Dcl-S count Packed(10:0) INZ(0);
Dcl-S last_fetch Ind INZ(*OFF); //Last fetch indicat
Dcl-S Command Char(80) INZ('DLYJOB DLY(1)'); //Used to hold scree
Dcl-S Command_length Packed(15:5) INZ(80); //Standard cmd lengt
Dcl-C OK CONST(0); // Successcode (SQL)
//
// Initialize lower/upper bounds in display file and show user.
//
lt_or_eq = lower_bound;
gt_or_eq = upper_bound;
Exfmt dspfrec;
//
// Read user-provided lower/upper bounds.
//
lower_bound = lt_or_eq;
upper_bound = gt_or_eq;
//
// Select from the file all records whose value is within the lower/upper bounds.
// Assign to cursor1 for fetching.
//
exec sql
declare cursor1 cursor for
select fld1, count(*)
from floatpf
where (fld1 >= :lower_bound) and (fld1 <= :upper_bound)
group by fld1
order by fld1;
//
// Open SQL cursor.
//
exec sql
open cursor1;
//
last_fetch = *off;
//
// Process all matching records in a loop.
//
DoU last_fetch = *on;
//
// Fetch next matching record.
//
exec sql
fetch cursor1
into :partial, :count;
If sqlcod = OK; // If successful fetch
total = total + partial; // Update total
n = n + 1; // Increaserec count
mean = total / n; // Recalculate mean
cur_val = partial; // Current val -> DSPF
cur_sum = total; // Current tot -> DSPF
cur_n = n; // Rec count -> DSPF
cur_mean = mean; //Current mean -> DSPF
Write dspfrec; // Show updated values
System_Command(Command:Command_Length); // Delay for user read
Else; // If fetch failed
last_fetch = *on; // End loop
EndIf;
EndDo;
//
// Change DSPF prompts for the final result, then display and leave on screen.
//
*in99 = *on;
Exfmt dspfrec;
//
// Close SQL cursor.
//
exec sql
close cursor1;
*inlr = *on; // End program
Compile using CRTSQLRPGI OBJ(<yourlib>/FLOAT4) SRCFILE(<yourlib>/QRPGLESRC) SRCMBR(FLOAT4) OBJTYPE(*PGM) Add a couple of records to file FLOATPF using SQL: insert into floatpf values('123.E0') insert into floatpf values('234.E0') Call the program from command line ===> call float4 Enter the values for Lower Bound and Upper Bound and press Enter![]()
A Note on Complex Numbers Specific ILE-bindable CEE math APIs are available in different versions, some taking complex numbers as arguments. While it does not exist in native form on OS/400, the complex data type can be implemented as a data structure containing two floating point fields; depending on how the component fields are defined, a complex variable may be single- or double-precision. Of all ILE languages, ILE C is best suited for handling this data type. The appropriate definitions can be found in the header file QSYSINC/H,LETYPE and the relevant API prototypes are in QSYSINC/H,LEMATH. 5770SS1 option 13 must be installed for library QSYSINC to be loaded on the system. The following code samples illustrate how to invoke the API for complex number multiplication using ILE RPG IV. The actual invocation is done via an ILE C module. The two modules are intended to be bound into a single program, the ILE RPG IV module being the entry point. ILE RPG Source FLOAT6
**FREE
// This ILE RPG module indirectly uses API CEESEMLT to perform complex number
// multiplication. The multiplication is performed via an intermediate C function,
// which transfers the operands to appropriate data structures, calls the API, and
// returns the result.
// Complex variables are defined in the source code as pairs of double-precision
// fields. This is because, unlike C, RPG does not readily allow for defining
// data structures as data types.
//
Dcl-S Std_Double Float(8); //data type definiti
Dcl-S var1_r like(Std_Double); // 1stoperand (real)
Dcl-S var1_i like(Std_Double); // 1stoperand (imag)
Dcl-S var2_r like(Std_Double); // 2ndoperand (real)
Dcl-S var2_i like(Std_Double); // 2ndoperand (imag)
Dcl-S result_r like(Std_Double); // result (real)
Dcl-S result_i like(Std_Double); // result (imag)
//
// Definition of C function prototype. The function's arguments are 3 pairs of
// double-precision variables: the first two pairs for the two operands to be
// multiplied, and the last pair for the function to return the result.
//
//
// Internal prototype name is complex_c; external name of C function is
// 'complex_multiply' (the external name is case-sensitive).
//
Dcl-Pr complex_c extproc('complex_multiply');
//
// First operand
//
parm1 like(Std_Double) value;
parm2 like(Std_Double) value;
//
// Second operand
//
parm3 like(Std_Double) value;
parm4 like(Std_Double) value;
//
// The last two fields are passed by address, to allow the C function to return
// the multiplication's result.
//
parm5 Pointer value;
parm6 Pointer value;
End-Pr;
//
// Set first operand to 1 + 2i
//
var1_r = 1;
var1_i = 2;
//
// Set second operand to 1 - 2i
//
var2_r = 1;
var2_i = -2;
//
// Multiply operands and return result
//
complex_c(var1_r : var1_i : var2_r : var2_i :
%addr(result_r) : %addr(result_i));
//
// The LR indicator needs to be turned on to signal end of program. Note: this module
// is the ILE program's entry point.
//
*inlr = *on;
ILE C Source FLOATC
/*
This C module is designed as an interface between ILE RPG (or other ILE languages
supporting the double-precision data type) and API CEESEMLT, which multiplies
double-precision complex numbers. The (ILE RPG) calling module sends each complex
parameter as a pair of double-precision parameters. The C function complex_multiply
transfers the values to variables of type _COMPLEX16 (double-precision complex;see
definition in QSYSINC/H,LETYPE), then invokes CEESEMLT. The API is prototyped in
QSYSINC/H,LEMATH.
*/
/* Header letype.h contains the definitions for data types _COMPLEX16 and _FEEDBACK. */
#include <letype.h>
/* Header lemath.h contains the prototype for API CEESEMLT. */
#include <lemath.h>
/* Definitions of first operand, second operand, result for complex multiplication. */
_COMPLEX16 var1, var2, result;
/* Feedback area for API to return any errors. */
_FEEDBACK fc;
/*
The function below interfaces with a caller, in this case written in ILE
RPG, and with the complex multiplication API CEESEMLT. The arguments
represent:
(1) Real part of first operand
(2) Imaginary part of first operand
(3) Real part of second operand
(4) Imaginary part of second operand
(5) Real part of result
(6) Imaginary part of result
The arguments are 6 individually defined double-precision fields, rather
than 3 complex data structures; this is intended to allow interfacing of
the function with languages not having the data structure facilities
needed to call the API directly.
*/
void complex_multiply(double arg1r, double arg1i, double arg2r, double arg2i,
double * result_r, double * result_i)
{
/* Load real and imaginary parts of first operand into data structure. */
var1.real = arg1r;
var1.imaginary = arg1i;
/* Load real and imaginary parts of second operand into data structure. */
var2.real = arg2r;
var2.imaginary = arg2i;
/* Invoke API */
CEESEMLT(&var1, &var2, &result, &fc);
/* Load real and imaginary parts of result into arguments and return to caller. */
*result_r = result.real;
*result_i = result.imaginary;
return;
}
Compile ILE RPG IV module:
CRTRPGMOD MODULE(<yourlib>/FLOAT6) SRCFILE(<yourlib>/QRPGLESRC) SRCMBR(FLOAT6) DBGVIEW(*ALL)
Compile ILE C module:
CRTCMOD MODULE(<yourlib>/FLOATC) SRCFILE(<yourlib>/QCSRC) SRCMBR(FLOATC) DBGVIEW*(*ALL)
CRTRPGMOD MODULE(<yourlib>/FLOAT6) SRCFILE(<yourlib>/QRPGLESRC) SRCMBR(FLOAT6) DBGVIEW(*ALL)
Compile ILE C module:
CRTCMOD MODULE(<yourlib>/FLOATC) SRCFILE(<yourlib>/QCSRC) SRCMBR(FLOATC) DBGVIEW*(*ALL)
Create the program:
CRTPGM PGM(FLOAT6) MODULE(FLOAT6 FLOATC) ACTGRP(*NEW)
Run the program in debug:
Run the program in debug:
strdbg float6
call float6 and examine the variables
> EVAL var1_r
VAR1_R = 1.000000000000E+000
> EVAL var1_i
VAR1_I = 2.000000000000E+000
> EVAL var2_r
VAR2_R = 1.000000000000E+000
> EVAL var2_i
VAR2_I = -2.000000000000E+000
> EVAL result_r
RESULT_R = 5.000000000000E+000
> EVAL result_i
RESULT_I = 0.000000000000E+000
VAR1_R = 1.000000000000E+000
> EVAL var1_i
VAR1_I = 2.000000000000E+000
> EVAL var2_r
VAR2_R = 1.000000000000E+000
> EVAL var2_i
VAR2_I = -2.000000000000E+000
> EVAL result_r
RESULT_R = 5.000000000000E+000
> EVAL result_i
RESULT_I = 0.000000000000E+000
[{"Type":"MASTER","Line of Business":{"code":"LOB68","label":"Power HW"},"Business Unit":{"code":"BU070","label":"IBM Infrastructure"},"Product":{"code":"SWG60","label":"IBM i"},"ARM Category":[{"code":"a8m3p000000hB4rAAE","label":"API"},{"code":"a8m0z0000000CHtAAM","label":"Programming ILE Languages"}],"ARM Case Number":"","Platform":[{"code":"PF012","label":"IBM i"}],"Version":"All Versions"}]
Historical Number
16265257
Was this topic helpful?
Document Information
Modified date:
24 November 2024
UID
nas8N1018038
A Note on Complex Numbers
Specific ILE-bindable CEE math APIs are available in different versions, some taking complex numbers as arguments.
While it does not exist in native form on OS/400, the complex data type can be implemented as a data structure containing two floating point fields;
depending on how the component fields are defined, a complex variable may be single- or double-precision.
Of all ILE languages, ILE C is best suited for handling this data type.
The appropriate definitions can be found in the header file QSYSINC/H,LETYPE and the relevant API prototypes are in QSYSINC/H,LEMATH.
5770SS1 option 13 must be installed for library QSYSINC to be loaded on the system.
The following code samples illustrate how to invoke the API for complex number multiplication using ILE RPG IV.
The actual invocation is done via an ILE C module.
The two modules are intended to be bound into a single program, the ILE RPG IV module being the entry point.
ILE RPG Source FLOAT6