Berkeley TestFloat Release 3e: testfloat_gen

John R. Hauser
2018 January 20

Overview

The testfloat_gen program generates test cases for testing that an implementation of floating-point arithmetic conforms to the IEEE Standard for Binary Floating-Point Arithmetic. testfloat_gen is part of the Berkeley TestFloat package, a small collection of programs for performing such tests. For general information about TestFloat, see file TestFloat-general.html.

A single execution of testfloat_gen generates test cases for only a single floating-point operation and associated options. The testfloat_gen program must be repeatedly executed to generate test cases for each operation to be tested.

The testfloat_gen program writes the test cases it generates to standard output. This output can either be captured in a file through redirection, or be piped to another program that exercises a floating-point operation using the test cases as they are supplied. Depending on use, the total output from testfloat_gen can be large, so piping to another program may be the best choice to avoid using inordinate file space. The format of testfloat_gen’s output is raw hexadecimal text, described in the section below titled Output Format.

Command Syntax

The testfloat_gen program is executed as a command in one of these forms:

testfloat_gen [<option>...] <type>
testfloat_gen [<option>...] <function>
Square brackets ([ ]) denote optional arguments, and <option> is a supported option, documented below. A testfloat_gen command expects either a <type> specifying the type and number of outputs or a <function> naming a floating-point operation. If testfloat_gen is executed without any arguments, a summary of usage is written.

A <type> can be one of the following:

ui32 unsigned 32-bit integers
ui64 unsigned 64-bit integers
i32 signed 32-bit integers
i64 signed 64-bit integers
f16 [<num>] one or more 16-bit half-precision floating-point values
f32 [<num>] one or more 32-bit single-precision floating-point values
f64 [<num>] one or more 64-bit double-precision floating-point values
extF80 [<num>]    one or more 80-bit double-extended-precision floating-point values
f128 [<num>] one or more 128-bit quadruple-precision floating-point values
Optional <num> is one of 1, 2, or 3. If a <type> is given without <num> (such as ui32 or f64), testfloat_gen outputs a list of values of the specified type, one value per line, appropriate for testing a floating-point operation with exactly one operand of the given type. If a floating-point type and number are given (such as f32 2 or extF80 1), testfloat_gen outputs the specified number of values per line, appropriate for testing a floating-point operation with that number of operands. Although the exact operation being tested is not specified, the test cases output by testfloat_gen cover all standard floating-point operations, to the degree explained in TestFloat-general.html.

If a <function> operation name is given, then each line of output from testfloat_gen contains not only the operands for that operation (as would be generated by an appropriate <type> argument) but also the expected results as determined by testfloat_gen’s internal floating-point emulation (Berkeley SoftFloat). The available operation names are listed in TestFloat-general.html. In all cases, floating-point operations have two results: first, a value, which may be floating-point, integer, or Boolean, and, second, the floating-point exception flags raised by the operation. If the output from a tested floating-point operation does not match the expected output specified by testfloat_gen, this may or may not indicate an error in the floating-point operation. For further explanation, see TestFloat-general.html, especially the section titled Variations Allowed by the IEEE Floating-Point Standard.

Options

The testfloat_gen program accepts several command options. If mutually contradictory options are given, the last one has priority.

-help

The -help option causes a summary of program usage to be written, after which the program exits.

-prefix <text>

The -prefix option causes testfloat_gen to write the supplied text argument verbatim as the first line of output before any test cases. This can be used, for example, to indicate to a downstream program what kind of test to perform for the test cases that follow.

-seed <num>

The -seed option sets the seed for the pseudo-random number generator used for generating test cases. The argument to -seed is a nonnegative integer. Executing the same testfloat_gen program with the same arguments (including the same pseudo-random number seed) should always generate the same sequence of test cases, whereas changing the pseudo-random number seed should result in a different sequence of test cases. The default seed number is 1.

-level <num>

The -level option sets the level of testing. The argument to -level can be either 1 or 2. The default is level 1. Level 2 causes many more test cases to be generated, with better coverage, than level 1.

-n <num>

Option -n specifies the number of test cases to generate. For each <type> or <function> and each testing level (set by -level), there is a minimum value that testfloat_gen will accept for <num>. If no -n option is given, the number of test cases generated by testfloat_gen equals the minimum value acceptable for the -n argument. Option -n cannot be used to reduce this number, but can increase it, without changing the testing level.

-forever

The -forever option causes test cases to be generated indefinitely, without limit (until the program is terminated by some external cause). The testing level is set to 2 by this option.

-precision32, -precision64, -precision80

When a <function> is specified that is an 80-bit double-extended-precision operation affected by rounding precision control, the -precision32 option sets the rounding precision to 32 bits, equivalent to 32-bit single-precision. Likewise, -precision64 sets the rounding precision to 64 bits, equivalent to 64-bit double-precision, and -precision80 sets the rounding precision to the full 80 bits of the double-extended-precision format. All these options are ignored for operations not affected by rounding precision control. When rounding precision is applicable but not specified, the default is the full 80 bits, same as -precision80.

-rnear_even, -rnear_maxMag, -rminMag, -rmin, -rmax, -rodd

When a <function> is specified that requires rounding, the -rnear_even option sets the rounding mode to nearest/even; -rnear_maxMag sets rounding to nearest/maximum magnitude (nearest-away); -rminMag sets rounding to minimum magnitude (toward zero); -rmin sets rounding to minimum (down, toward negative infinity); -rmax sets rounding to maximum (up, toward positive infinity); and -rodd, if supported, sets rounding to odd. These options are ignored for operations that are exact and thus do not round. When rounding mode is relevant but not specified, the default is to round to nearest/even, same as -rnear_even.

-tininessbefore, -tininessafter

When a <function> is specified that requires rounding, the -tininessbefore option indicates that tininess on underflow will be detected before rounding, while -tininessafter indicates that tininess on underflow will be detected after rounding. These options are ignored for operations that are exact and thus do not round. When the method of tininess detection matters but is not specified, the default is to detect tininess on underflow after rounding, same as -tininessafter.

-notexact, -exact

When a <function> is specified that rounds to an integer (either conversion to an integer type or a roundToInt operation), the -notexact option indicates that the inexact exception flag is never raised, while -exact indicates that the inexact exception flag is to be raised if the result is inexact. For other operations, these options are ignored. If neither option is specified, the default is not to raise the inexact exception flag when rounding to an integer, same as -notexact.

Output Format

For each test case generated, testfloat_gen writes a single line of text to standard output. When the testfloat_gen command is given a <type> argument, each test case consists of either one integer value or one, two, or three floating-point values. Each value is written to output as a raw hexadecimal number. When there is more than one value per line, they are separated by spaces. For example, output from executing

testfloat_gen f64 2
might look like this:
3F90EB5825D6851E C3E0080080000000
41E3C00000000000 C182024F8AE474A8
7FD80FFFFFFFFFFF 7FEFFFFFFFFFFF80
3FFFED6A25C534BE 3CA1000000020000
...
with each hexadecimal number being one 64-bit floating-point value. Note that, for floating-point values, the sign and exponent are at the most-significant end of the number. Thus, for the first number on the first line above, the leading hexadecimal digits 3F9 are the sign and encoded exponent of the 64-bit floating-point value, and the remaining digits are the encoded significand.

When testfloat_gen is given a <function> operation name, each line of output has not only the operands for the operation but also the expected output, consisting of a result value and the exception flags that are raised. For example, the output from

testfloat_gen f64_add
could include these lines:
3F90EB5825D6851E C3E0080080000000 C3E0080080000000 01
41E3C00000000000 C182024F8AE474A8 41E377F6C1D46E2D 01
7FD80FFFFFFFFFFF 7FEFFFFFFFFFFF80 7FF0000000000000 05
3FFFED6A25C534BE 3CA1000000020000 3FFFED6A25C534BF 01
...
On each line, the first two numbers are the operands for the floating-point addition, and the third and fourth numbers are the expected floating-point result (the sum) and the exception flags raised. Exception flags are encoded with one bit per flag as follows:
bit 0    inexact exception
bit 1underflow exception
bit 2overflow exception
bit 3 infinite exception (“divide by zero”)
bit 4invalid exception