Keil Logo

Technical Support

On-Line Manuals

Libraries and Floating Point Support Guide

Preface The ARM C and C++ Libraries The ARM C Micro-library Floating-point Support About floating-point support The software floating-point library, fplib Calling fplib routines fplib arithmetic on numbers in a particular format fplib conversions between floats, long longs, doub fplib comparisons between floats and doubles fplib C99 functions Controlling the ARM floating-point environment Floating-point functions for compatibility with Mi C99-compatible functions for controlling the ARM f C99 rounding mode and floating-point exception mac Exception flag handling Functions for handling rounding modes Functions for saving and restoring the whole float Functions for temporarily disabling exceptions ARM floating-point compiler extensions to the C99 Writing a custom exception trap handler Example of a custom exception handler Exception trap handling by signals mathlib double and single-precision floating-point IEEE 754 arithmetic Basic data types for IEEE 754 arithmetic Single precision data type for IEEE 754 arithmetic Double precision data type for IEEE 754 arithmetic Sample single precision floating-point values for Sample double precision floating-point values for IEEE 754 arithmetic and rounding Exceptions arising from IEEE 754 floating-point ar Exception types recognized by the ARM floating-poi Using the Vector Floating-Point (VFP) support libr The C and C++ Library Functions reference Floating-point Support Functions Reference

Writing a custom exception trap handler

3.3.9 Writing a custom exception trap handler

Custom exception trap handlers let you override the default exception handling behavior. For example, when converting Fortran code you might want to override the division by zero exception to return 1 rather than an invalid operation exception.


The following functionality requires you to select a floating-point model that supports exceptions, such as --fpmode=ieee_full or --fpmode=ieee_fixed.
If you want to install a custom exception trap handler, declare it as a function like this:
__softfp __ieee_value_t myhandler(__ieee_value_t op1,
                                  __ieee_value_t op2,
                                  __ieee_edata_t edata);
The value returned from this function is of type __ieee_value_t and is used as the result of the operation that caused the exception.
The function must be declared __softfp in order to be usable as a handler.
The parameters to this function are:
op1, op2
These specify the operands, or the intermediate result, for the operation that caused the exception:
  • For the Invalid Operation and Divide by Zero exceptions, the original operands are supplied.
  • For the Inexact Result exception, all that is supplied is the ordinary result that would have been returned anyway. This is provided in op1.
  • For the Overflow exception, an intermediate result is provided. This result is calculated by working out what the operation would have returned if the exponent range had been big enough, and then adjusting the exponent so that it fits in the format. The exponent is adjusted by 192 (0xC0) in single-precision, and by 1536 (0x600) in double-precision.
    If Overflow happens when converting a double to a float, the result is supplied in double format, rounded to single-precision, with the exponent biased by 192.
  • For the Underflow exception, a similar intermediate result is produced, but the bias value is added to the exponent instead of being subtracted. The edata parameter also contains a flag to show whether the intermediate result has had to be rounded up, down, or not at all.
The type __ieee_value_t is defined as a union of all the possible types that an operand can be passed as:
typedef union{
    float __f;
    float __s;
    double __d;
    short __h;
    unsigned short __uh;
    int __i;
    unsigned int __ui;
    long long __l;
    unsigned long long __ul;
                              /* __STRICT_ANSI__ */
    struct { int __word1, __word2; } __str;
} __ieee_value_t;             /* in and out values passed to traps */


If you do not compile with --strict, and you have code that used the older definition of __ieee_value_t which named the fields differently, your older code still works. See the file fenv.h for more information.
This contains flags that give information about the exception that occurred, and what operation was being performed. (The type __ieee_edata_t is a synonym for unsigned int.)

edata flags for exception trap handler

The flags contained in edata are:
edata & FE_EX_RDIR
This is nonzero if the intermediate result in Underflow was rounded down, and 0 if it was rounded up or not rounded. (The difference between the last two is given in the Inexact Result bit.) This bit is meaningless for any other type of exception.
edata & FE_EX_exception
This is nonzero if the given exception (INVALID, DIVBYZERO, OVERFLOW, UNDERFLOW, or INEXACT) occurred. This enables you to:
  • Use the same handler function for more than one exception type (the function can test these bits to tell what exception it is supposed to handle).
  • Determine whether Overflow and Underflow intermediate results have been rounded or are exact.
Because the FE_EX_INEXACT bit can be set in combination with either FE_EX_OVERFLOW or FE_EX_UNDERFLOW, you must determine the type of exception that actually occurred by testing Overflow and Underflow before testing Inexact.
This is nonzero if the FZ bit was set when the operation was performed.
This gives the rounding mode that applies to the operation. This is normally the same as the current rounding mode, unless the operation that caused the exception was a routine such as _ffix, that always rounds toward zero. The available rounding mode values are FE_EX_ROUND_NEAREST, FE_EX_ROUND_PLUSINF, FE_EX_ROUND_MINUSINF and FE_EX_ROUND_ZERO.
This gives the type of the operands to the function, as one of the type values shown in the following table.

Table 3-5 FE_EX_INTYPE_MASK operand type flags

Flag Operand type
FE_EX_INTYPE_FD float double
FE_EX_INTYPE_DF double float
FE_EX_INTYPE_UINT unsigned int
FE_EX_INTYPE_ULONGLONG unsigned long long
This gives the type of the operands to the function, as one of the type values shown in the following table.

Table 3-6 FE_EX_OUTTYPE_MASK operand type flags

Flag Operand type
FE_EX_OUTTYPE_UINT unsigned int
FE_EX_OUTTYPE_ULONGLONG unsigned long long
edata & FE_EX_FN_MASK
This gives the nature of the operation that caused the exception, as one of the operation codes shown in the following table.

Table 3-7 FE_EX_FN_MASK operation type flags

Flag Operation type
FE_EX_FN_ADD Addition.
FE_EX_FN_SUB Subtraction.
FE_EX_FN_MUL Multiplication.
FE_EX_FN_DIV Division.
FE_EX_FN_REM Remainder.
FE_EX_FN_RND Round to integer.
FE_EX_FN_SQRT Square root.
FE_EX_FN_CMP Compare.
FE_EX_FN_CVT Convert between formats.
FE_EX_FN_LOGB Exponent fetching.


The FE_EX_INTYPE_MASK flag only specifies the type of the first operand. The second operand is always an int.
Next representable number.


Both operands are the same type. Calls to nexttoward cause the value of the second operand to change to a value that is of the same type as the first operand. This does not affect the result.
FE_EX_FN_RAISE The exception was raised explicitly, by feraiseexcept() or feupdateenv(). In this case, almost nothing in the edata word is valid.
When the operation is a comparison, the result must be returned as if it were an int, and must be one of the four values shown in the following table.
Input and output types are the same for all operations except Compare and Convert.

Table 3-8 FE_EX_CMPRET_MASK comparison type flags

Flag Comparison
FE_EX_CMPRET_LESS op1 is less than op2
FE_EX_CMPRET_EQUAL op1 is equal to op2
FE_EX_CMPRET_GREATER op1 is greater than op2
FE_EX_CMPRET_UNORDERED op1 and op2 are not comparable
Non-ConfidentialPDF file icon PDF versionARM DUI0378H
Copyright © 2007, 2008, 2011, 2012, 2014-2016 ARM. All rights reserved. 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.