Copyright (C) 1995, 2008 Tydeman Consulting. All rights reserved. Fred Tydeman tydeman@tybor.com BRIEF HISTORY ----- ------- Several years ago, the Numerical C Extensions Group (NCEG) was formed by several C compiler vendors and users. Their goal was to develop extensions to the C language for numerical work. After a few years, they became a subgroup (x3j11.1) of the American National Standards Institute (ANSI) C programming language standards committee (x3j11). After a year or so, x3j11.1 became part of the parent body x3j11. In December, 1994, x3j11 voted to publish, as a Technical Report, its work on extending the C language for numerical work. Some time later, ANSI renamed itself to NCITS (and then INCITS) and dropped the x3 from the committee names, hence, the US "C" standards committee became INCITS J11. In 2008, they reorganized the committee structure, and J11 became PL22.11. The official number of the Numerical C Technical Report produced by X3J11 is X3/TR-17:1995. It should be available for purchase from: Global Engineering Documents 15 Inverness Way East Englewood, CO 80112-5704 Phone 1 (800) 624-3974 (toll free from USA and Canada only) +1 (303) 792-2181 Fax +1 (303) 397-7935 Part of that report is concerned with Floating-Point C Extensions (FPCE), which is a set of extensions to standardize on access to the floating-point environment for the C programmer. Three major parts of FPCE are defining how the user can access the IEEE-754 floating-point environment, constraints on the compiler with respect to code generation to conform to IEEE-754, and behavior of the math library for IEEE-754 arguments and results. Most floating-point units designed and built after 1985 are IEEE-754 in format, if not detail. That includes most PCs and workstations and some mainframes. More on FPCE can be found in "An Introduction to Floating-Point C Extensions" by Jim Thomas and Jerome T. Coonen in the C/C++ Users Journal, January 1995, Volume 13, Number 1, pages 49 to 57. That article, along with the FPCE document, can be obtained by anonymous FTP or web access from (I believe): ftp://ftp.dmk.com/DMK/sc22wg14/c9x/floating-point http://www.dmk.com Another place to look is the book: Inside Macintosh: PowerPC Numerics by Apple Computer, 1994, Addison- Wesley Publishing Company. The core features of PowerPC Numerics are based upon IEEE-754 and FPCE. The international C programming language standards committee, ISO WG14, has co-located meetings with J11. Some committee documents are posted to the above dmk ftp site and some to (I believe): http://www.open-std.org/jtc1/sc22/wg14/www/documents http://www.dkuug.dk/JTC1/SC22/WG14/docs ftp://dkuug.dk/JTC1/SC22/WG14/docs The C language was revised by J11 and WG14 over the past several years. When the revision was started, we planned to be done by year end 1999, so the work in progress was called C9X. At the June, 1996, meeting, FPCE was voted into C9X (pending review by an editorial committee). At the October, 1996, meeting, FPCE (final words) were voted into C9X. The Committee Document draft 1 (CD1) of C9X can be found at (I believe): http://www.open-std.org/jtc1/sc22/wg14/www/documents/n643 http://www.dkuug.dk/JTC1/SC22/open/n2620 A second version of C9X was sent for review. It was called CD2, but it is now being called the Final Committee Document (FCD). One place to find it is (I believe): http://www.open-std.org/jtc1/sc22/wg14/www/documents/n843 ftp://ftp.dmk.com/DMK/sc22wg14/review In December, 1999, the latest official version of C, called C99, was published. It's official number is: ISO/IEC 9899:1999(E). It is available for purchase (for about $18) from (I believe): http://www.cssinfo.com/ncitsgate.html http://webstore.ansi.org/ansidocstore/find.asp?find_spec=9899 In September, 2001, the Technical Corrigendum 1 (TC1) to C99 was published. The main item of interest to FPCE is the inclusion of Defect Report (DR) 202. That DR changed the return type of the functions that used to return void, so that they now return int, and the int value is a success/failure indicator. The other math related DR is 210. These DRs (and others) can be found at (I believe): http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm http://www.dkuug.dk/jtc1/sc22/wg14/www/docs/summary.html In November, 2004, the Technical Corrigendum 2 (TC2) to C99 was published. The main item of interest to FPCE is the inclusion of Defect Reports (DR) 207, 211, 218, 223, 224, 225, 233, 238, 239, 240, 241, 242, 243, 244, 275, and 285. These DRs (and others) can be found at (I believe): http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm http://www.dkuug.dk/jtc1/sc22/wg14/www/docs/summary.html DRs that will change the C standard, once they are published in a Technical Corrigendum are: 287, 290, 291, 293, 296, 297. TC1 and TC2 can be obtained, as free downloads, at (I believe): http://webstore.ansi.org/ansidocstore/find.asp?find_spec=9899 In late 2005, WG14 published a document that is C99 + TC1 + TC2 as (I believe): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf http://www.dkuug.dk/jtc1/sc22/wg14/www/docs/n1124.pdf It is available free of charge. Both the old (C89) and new (C99) rationales are now on-line at: ftp://ftp.dmk.com/DMK/sc22wg14/rationale The October, 1999, draft of the C99 rationale is available from the WG14 web site at: http://www.dkuug.dk/jtc1/sc22/wg14/www/docs/n897.pdf The Febuary 2004, draft of the C99 rationale is available from the WG14 web site at: http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf There are four related standards dealing with floating-point. ANSI/IEEE Std 754-1985 --+--> ANSI/IEEE Std 854-1987 | +--> IEC 559-1989 --> IEC 60559-1989 IEEE-754 is: IEEE Standard for Binary Floating-Point Arithmetic. The paper document number is: SH10116. Most floating-point hardware these days supports 754 in format, if not detail. As of 2001-2006, there are meetings in progress to revise this standard. A message "subscribe stds-754" to majordomo@majordomo.ieee.org will subscribe you. Past meeting minutes appear to be online at the www.ieee.org web site. IEEE-854 is: IEEE Standard for Radix-Independent Floating-Point Arithmetic. The paper document is: SH11460. This extends 754 by adding decimal radix (base 10) support. Some hand held calculators use the decimal part of this standard. IEC 559 is: Binary floating-point arithmetic for microprocessor systems. This is the international version of 754 and supposed to be the same as IEEE-754, but the paper copy I have has several editing errors in it (and they changed the meaning of 754). Note: there are two IEC 559 standards (the other one has to do with pipes). IEC 60559 is just IEC 559 renumbered (so as to not conflict with the 559 pipe standard). Online information can be found at: http://www.ieee.org For 754 and 854 http://www.iso.org For 559 http://www.iec.ch For 60559 For those who wish to support Signaling NaNs (part of IEEE-754 that was not adopted into C99), you should check out: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1011.htm http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n1011.htm Several C compiler and library vendors already have products that support major parts of FPCE: Zortech, in 1991, modified their C/C++ compiler to support FPCE as it stood then (NCEG 91-015). Since then, they were aquired by Symantec, and then spunoff into Digital Mars. Taligent, now part of IBM, in 1994, had me develop a test suite to make sure their C/C++ compiler (but not library) conforms to C9X FPCE as it stood then (WG14/N350, X3J11/94-035). Since then, other parts of IBM have started using my full C99 FPCE Test Suite to check their compilers, headers, and math libraries. Cray has support for most of the C9X version of FPCE and is using my test suite to check their compiler, headers, and math library. Hewlett-Packard has support for the C99 version of FPCE and is using my test suite to check their compiler, headers, and math library. Tandem, aquired by Compaq, merged with HP, has support for most of the C9X version of FPCE and is using my test suite to check their compiler, headers, and math library. Dinkumware has support for the C99 version of FPCE and is using my test suite to check their headers and math library. Sun has support for the C99 version of FPCE and is using my test suite to check their compiler, headers, and math library. EDG (Edison Design Group) has support for the C99 version of FPCE and is using my test suite to check their compiler front end. I have run the FPCE test suite against many compilers on Unix, Linux, OS/2, eCS, x86 Solaris, Sun Sparc Solaris, Apple Mac OS X, DOS, and Windows 3.1, NT 4, 98, and XP; of which only some of the compilers claim to support FPCE. All the compilers fail some of my tests of compliance to the previous Standard C, also known as C89, as well as fail some of my tests of compliance to FPCE (C99+IEEE754). For a list of the bugs found, please look at the file mydefs.h, which has DISALLOW_* symbols to bypass the tests that catch those bugs. I own a derivative of Taligent's FPCE test suite (mine has changed as the FPCE proposal has evolved over the years), so can license it to others. Here are some test cases from that FPCE test suite. You are welcome to copy these test cases and their support files for your own non-commercial use. The latest version of the sample FPCE tests can be obtained by anonymous FTP from: ftp://ftp.tybor.com user ID: anonymous password: your email address You may also request them by sending e-mail to tydeman@tybor.com. There are seven sample tests here: These first four can be run "as is": tbin2dec C89: Test of printf() of binary to decimal conversions of double. tsin C89: Test of sin(355.0). tflt2int C99: Test of float type to integer type conversion. tint2flt C99: Test of integer type to float type conversion. These next three require configuration files be setup first: t0120200 Test of compiler code generation for float -> int conversions. t1150000 Test of math library sin() for IEEE-754 values. t1150001 Test of math library sin() for general values. In the messages from these tests, "FUT" means Function Under Test. Files in these sample FPCE tests: ----- -- ----- ------ ---- ----- readme.1st This file. Instructions on how to install, tailor, and use the sample tests. readme.2nd List of files in the entire FPCE Test Suite. Instructions on how to install, tailor, and use the entire FPCE test suite. pkzip.zip All the sample FPCE files gathered together into one file and compressed into a PKZIP compatible file. Makes for easier getting of the files from the FTP site. When expanded, these files have DOS line ends. targzip.gz All the sample FPCE files gathered together into one file (used TAR) and compressed (used GZIP) into one file. Makes for easier getting of the files from the FTP site. When expanded, these files have Unix line ends. tbin2dec.c Standalone test of binary to decimal conversion of double floating-point values via sprintf(). It does not need any other FPCE test suite files. tsin.c Standalone test of sin(355.0). It does not need any other FPCE test suite files. tflt2int.c Standalone test of float type to integer type conversion in C99. This is a easy to run version of t0120200. Needs . It does not need any other FPCE test suite files. tint2flt.c Standalone test of integer type to float type conversion in C99. This is a easy to run version of t0120400. Needs . It does not need any other FPCE test suite files. t0120200.c A sample compiler code generation test case. This is a wrapper file to include the support code and the actual test so that they can be compiled all at once (this avoids having to do separate compiles followed by a linkedit of various object files). t1150000.c A sample math library test case. This is a wrapper file to include the support code and the actual test so that they can be compiled all at once (this avoids having to do separate compiles followed by a linkedit of various object files). t1150001.c A sample math library test case. This is a wrapper file to include the support code and the actual test so that they can be compiled all at once (this avoids having to do separate compiles followed by a linkedit of various object files). t0120200.fjt The actual test of compiler code generation. Assertion being tested: For conversion from floating-point to integer type, large, out of range, integer floating-point values converted to integer types raises the IEEE-754 invalid operation exception. Also, tests that integer floating-point values in range do not raise any exceptions. This tests going from all floating-point types to all integral types. There are several debugging #defines at the beginning that may be uncommented (or defined in sample.h) to try to help locate problems with the compiler you are testing. t1150000.fjt The actual test of sin(). Assertion being tested: sin() is the sine() function. This is for IEEE-754 test vectors. t1150001.fjt The actual test of sin(). Assertion being tested: sin() is the sine() function. This is for general test vectors that should work on all systems. g1150000.h The generic sin() test code; included by t115000*.fjt. v1150000.h The sin() IEEE-754 test vectors; included by G1150000.h. v1150001.h The sin() general test vectors; included by G1150000.h. s0000000.fjt Support code needed by other FPCE tests. It has code to print out floating-point values in hexadecimal, code to determine the value of the Unit in the Last Place (ULP) of a floating-point value (which is needed to compute errors in the sin() function), and code to get the floating-point environment control modes (rounding, precision, trapping). sample.h Configuration file for these sample FPCE tests. Contains SAMPLE_* macros to be defined (or not) if a feature is missing from the compiler you are testing. mydefs.h Documentation on macro symbols used in the FPCE Test Suite. This also lists all the bugs in existing compilers, headers, and libraries found by the FPCE test suite and how to bypass those bugs (so that the tests run clean). This file includes sample.bug. sample.bug An example of a minimal configuration file for a compiler. It should let you compile and run the sample tests. This file is included by mydefs.h (which has the descriptions of the macro symbols). This needs to be tailored for each compiler you wish to test. This file contains macro #define's for how the tests should run (stand alone main() or C++ member function, output to console or file, any setup required to make a test run or to alter the environment to what FPCE expects), what optional features should be tested, what required features should be bypassed (because of bugs in the compiler, headers, or library). As shipped, it uses "fenvsamp.h" instead of and it uses the dummy fe*execpt() functions. That should allow you to compile, link, and run (but you may have many errors at runtime). sample2.bug Another example of a configuration file for a compiler. By the use of these #define's of DISALLOW_* macro symbols, certain tests are bypassed so that the test appears to run clean. sample3.bug Another example of a configuration file for a compiler. This one is for compilers that have not heard of . myfloat.h Description of the floating-point and integer characteristics of the system being tested. FPCE hex (if supported, else, decimal) constants of float.h values. This file includes sample.flt. sample.flt An example of a hardware definition file for a compiler. This one is based upon so that few modifications to this file will be required to run these sample tests. This file is included by myfloat.h (which has the descriptions of the macro symbols). myfuncs.h Prototypes of support functions needed by some FPCE tests. leaf.h ck() macro, SetSuccess() macro and some global variables. fpcelic.txt Sample license agreement. fenvsamp.h A header file (that is supposed to be supplied by the compiler vendor (as ) in a true FPCE environment). This has just what is needed to compile these sample test cases. This needs to be tailored for each compiler you wish to test. If you are using the dummy fe*except() functions (the default), then you may leave it as is. fenvdumy.h A dummy that has a macro for each function so that code can compile and run. It can be used with compilers that have never heard of . This allows the math library test to run and check accuracy, but ignore exceptions. fenvx87.h A dummy that has a macro for each function not needed by these sample tests and real functions for fe*except() and fe*round() in terms of common _*87() functions found on many Intel 80x86/80x87 compilers. In a true FPCE / C99 environment, these next four would be provided by the compiler vendor in an object library to be used at linkedit time. If you need to use any of these, they must be tailored for each compiler you wish to test. You also need to enable their usage by #define'ing the appropriate symbol in sample.h. fetestex.c Sample fetestexcept() implementation. fecleare.c Sample feclearexcept() implementation. feraisee.c Sample feraiseexcept() implementation. fegetrou.c Sample fegetround() implementation. Files that you may need to modify: sample.h sample.bug sample.flt fenvsamp.h fenvdumy.h fenvx87.h fetestex.c fecleare.c feraisee.c fegetrou.c Files that should remain as is: readme.1st t0120200.c readme.2nd t1150000.c pkzip.zip t1150001.c targzip.gz s0000000.fjt fpcelic.txt t0120200.fjt tbin2dec.c t1150000.fjt tsin.c t1150001.fjt mydefs.h g1150000.h myfloat.h v1150000.h myfuncs.h v1150001.h leaf.h sample2.bug tflt2int.c tint2flt.c INSTALLATION ------------ 0) Pick a directory to put these files into. A suggested location is: a) On DOS: C:\fpcets\sample\ b) On Unix: ~/fpcets/sample/ 1) If you got either pkzip.zip or targzip.gz, then run the following command(s) to expand the one compressed file into the 25 or so ASCII source files. (If the files came via email, you may need to do uudecode first, but your email program should have done it). a) pkzip.zip: DOS / Windows Unix / Linux pkunzip -d pkzip.zip or unzip -aa -a -L pkzip.zip b) targzip.gz: Unix / Linux Unix / Linux gunzip targzip.gz or gzip -d targzip.gz tar -v -x -f targzip or tar -vxf targzip There are three line end conventions. Unix uses one, Mac uses a second, and DOS, Windows 3.1/95/NT/XP and OS/2 use a third. If you get control-M (^M) characters at the end of each source line, or if the source appears to be double spaced, or the source is one very long line, then you need to convert the line end conventions. Some editors will do it. Some utilities, such as 'flip -u', 'flip -m', or 'gunzip -a' may do it. 2) There are two tests that are independent of the FPCE Test Suite and of C99 changes since C89. They can be compiled and run without having to do any setup first. It would be nice if you would report back to Tydeman the results of these two tests. a) Compile and run tbin2dec.c. A line of output with zero failures is best. More likely, you will get several lines of output with information about each failure. b) Compile and run tsin.c. The output will indicate about how many bits are wrong in the value computed for sin(355.0). 0 bits wrong is best. 3) There are two tests that are independent of the FPCE Test Suite, but do depend upon of C99 and support for IEEE-754 or IEC-60559. a) Compile and run tflt2int.c. There will be a header line for each pair of types being tested (a float type and an integer type), followed by any lines of failures (either wrong exception flags or computed value). b) Compile and run tint2flt.c. There will be a header line for each pair of types being tested (a float type and an integer type), followed by any lines of failures (either wrong exception flags or computed value). 4) The other three tests, which are part of the FPCE Test Suite, require tailoring configuration files first before they are compiled and run. The configuration files are: sample.bug, sample.flt, and sample.h. a) Edit sample.bug. You most likely need to review (#define or #undef as appropriate): STANDALONE_TEST REDIRECT SETUP1 SETUP2 FPU_* TEST_* DISALLOW_* NEED_* REMAP_* sample.bug should be usable for a first pass. If you need to tailor it, look at sample2.bug and near #error in mydefs.h for other ideas on how to tailor sample.bug. For a first pass (unless you know these are supported), you may wish to: #define DISALLOW_FPCE_HEX #define DISALLOW_OVERLOAD #define DISALLOW_FUNCS_F #define DISALLOW_FUNCS_L #define DISALLOW_FUNCS_nan #define DISALLOW_FPCE_FUNCTIONS b) Edit sample.flt. You most likely need to review: PBF_SIGNED *_PREC FMT_* *_FLT *_DBL *_LDBL For running the t0120200 test case, you need the various types' bits of precision (*_PREC). For running the t115* test cases, you need the above and most of the floating-point values (*_FLT, *_DBL, *_LDBL). For a quick (and not so accurate) use of these tests, you can define the floating-point values to be the same as what is in , or even just the symbols, which is what the sample.flt file does. For better values, look at myfloat.h: the comments at the beginning and the lines around #error after the #elif's. If you would like a check of your sample.flt, contact tydeman @ tybor.com and have him send you t0000000.fjt. c) Edit sample.h. You most likely need to review: FPCE_TEST_LVL FPCE_SAMPLE WANT_CLEAN DEBUG FENV_H SAMPLE_* If required FPCE macros or functions are missing from the compiler being tested, then you need to define SAMPLE_* and try to use the sample versions. The sample versions are setup for three environments: Intel x86/x87, Sun SPARC, and dummy. The dummy ones do nothing, but will allow you to compile, link, and run. The dummy ones are the defaults. If you need any of the missing functions, then you also need to tailor the sample fenvsamp.h header file and one or more of: 1) fetestex.c has fetestexcept() 2) fecleare.c has feclearexcept() 3) feraisee.c has feraiseexcept() 4) fegetrou.c has fegetround() 5) Now you can compile and run the three tests. a) Compile t0120200.c and run. A single line of output means the compiler you are testing is FPCE compliant for that one test case. More likely, you will get several lines of output with information about each failure. To get more information about what is going on, in sample.h, #define DEBUG and either #undef or #define LMS_FMT_AS_HEX. The hierarchy of which file includes which file is: t0120200.c sample.h t0120200.fjt In the failure messages, mydefs.h the variables are named as: sample.bug limits.h Sign: fenv.h or fenvsamp.h s - signed myfloat.h u - unsigned sample.flt p - plain float.h (optional) leaf.h Type: stdio.h lli - long long int fetestex.c li - long int mydefs.h i - int sample.bug si - short int fenv.h or fenvsamp.h c - char float.h bi - bit field feraisee.c e - enum to hold 2-bit values mydefs.h ie - enum to hold int values sample.bug se - enum to hold short values fenv.h or fenvsamp.h float.h fecleare.c mydefs.h sample.bug fenv.h or fenvsamp.h float.h b) Compile t1150000.c and run. A single line of output means the compiler you are testing is FPCE compliant for that one test case (which consists of many test vectors). More likely, you will get several lines of output with information about each failure. The hierarchy of which file includes which file is: t1150000.c sample.h t1150000.fjt mydefs.h sample.bug stdio.h string.h float.h math.h fenv.h or fenvsamp.h myfloat.h sample.flt float.h (optional) myfuncs.h leaf.h stdio.h g1150000.h v1150000.h s0000000.fjt mydefs.h sample.bug limits.h stddef.h float.h math.h fenv.h or fenvsamp.h myfloat.h sample.flt float.h myfuncs.h fetestex.c mydefs.h sample.bug fenv.h or fenvsamp.h float.h feraisee.c mydefs.h sample.bug fenv.h or fenvsamp.h float.h fecleare.c mydefs.h sample.bug fenv.h or fenvsamp.h float.h fegetrou.c mydefs.h sample.bug fenv.h or fenvsamp.h float.h c) Compile t1150001.c and run. A single line of output means the compiler you are testing is FPCE compliant for that one test case. More likely, you will get several lines of output with information about each failure. The hierarchy of which file includes which file is the same as for t1150000.c, except: t1150001.c replaces t1150000.c v1150001.c replaces v1150000.c I am interested in setups for other systems and compilers, so I would appreciate e-mail back to me for what you did to sample.h, sample.bug, sample.flt, fenvsamp.h, fetestex.c, fecleare.c, feraisee.c, and fegetrou.c. I am interested in the FPCE implementation bugs found by these sample tests on the system you tested. Please e-mail results back to me. If you are interested in licensing the entire test suite for $10,000.00, please contact me. The test suite can be considered as two parts: Tests of the compiler, and tests of the library functions. The statistics on the two parts are: Files Lines Characters Assertions Test vectors Compiler 1738 381,364 11,382,836 1160 - Library 335 319,108 26,356,365 436 243,201 Those statistics do not count such things as documentation or makefiles. -- Fred Tydeman tydeman @ tybor.com