Document Number: WG14 N749/J11 97-112
C9X Revision Proposal
=====================
Title: LIA-1 Binding:
Author: Fred J. Tydeman
Author Affiliation: Tydeman Consulting
Postal Address: 3711 Del Robles Dr., Austin, Texas, USA, 78727
E-mail Address: tydeman@tybor.com
Telephone Number: +1 (512) 255-8696
Fax Number: +1 (512) 255-8696
Sponsor: WG14
Date: 1997-09-21
Proposal Category:
__ Editorial change/non-normative contribution
__ Correction
Y_ New feature
__ Addition to obsolescent feature list
__ Addition to Future Directions
__ Other (please specify) ______________________________
Area of Standard Affected:
__ Environment
__ Language
__ Preprocessor
Y_ Library
Y_ Macro/typedef/tag name
Y_ Function
Y_ Header
__ Other (please specify) ______________________________
Prior Art: None known.
Target Audience: Programmers writing programs that perform a
significant amount of numeric processing.___________________
Related Documents (if any):
WG14/N758 C9X and LIA-1 informative annex.
WG14/N756 LIA-1 Binding: Arithmetic exception => SIGFPE,
WG14/N755 LIA-1 Binding: to ,
WG14/N753 LIA-1 Binding: Rationale,
WG14/N752 LIA-1 Binding: Optional parts annex,
WG14/N751 LIA-1 Binding: Combined LIA-1 + IEC-559 annex,
WG14/N750 LIA-1 Binding: LIA-1 annex,
WG14/N748 LIA-1 Binding: Adding 'pole' from LIA-2,
WG14/N747 IEC 559 Binding: Signaling NaNs,
WG14/N693 Type-Generic Math Functions,
WG14/N528 C Binding for LIA-1,
WG14/N488 LIA-2 (math library),
WG14/N487 LIA-1 (arithmetic),
WG14/N486 LIA Overview,
WG14/N463 Impact of adding LIA-1,
WG14/N461 C Binding of LIA-1
Proposal Attached: _Y Yes __ No, but what's your interest?
Abstract: These changes are the fundamental changes to C to
allow support of ISO 10967-1 (LIA-1). They are being added
in their own header
Proposal:
Note: The '*' characters in the lefthand column are not part
of the proposal (they are useful for emacs M-x outline mode)
In the following, **bold text**, *italic text*,
`code sample` are the conventions used to indicate
text different from normal.
* -- Add to 6.8.6 Pragma directive:
#pragma STDC LIA_NOTIFY { UNDEF | IGNORE | FLAGS | TRAP }
and add to the list of forward references:
the LIA_NOTIFY pragma (7.x.4.1.1)
* -- Add a new library section (here called 7.x)
** **7.x Notification and additional utilities .**
The header declares several macros and functions
to support Language Independent Arithmetic. These are
additional limits (characteristics of the integer and
floating-point types), general integer utilities,
mathematical functions, notification and access to the
integer environment. The *integer environment* refers
collectively to any integer status flags and control modes
supported by the implementation[footnote]. An *integer
status flag* is a system variable whose value is set as a
side effect of the arithmetic to provide auxiliary
information. An *integer control mode* is a system
variable whose value may be set by the user to affect the
subsequent behavior of the arithmetic.
[footnote]. This header is designed to support the
notification indicators (here called exception status flags)
required by LIA-1, and other similar integer state
information. Also it is designed to facilitate code
portability among all systems.
*** **7.x.1 Limits**
Several macros are declared to provide additional
information beyond and
about the characteristics of the integer and floating-point
types.
All integral values in the header, shall be
constant expressions suitable for use in #if preprocessing
directives; all floating values shall be constant
expressions. Most floating-point related macros have
separate names for all three floating-point types.
**** **7.x.1.1 Integer limits**
The treatment of out-of-bounds results
0 undefined behavior
1 wrap (similar to unsigned)
2 notification
for the signed integer types **int**, **long** and
**long long** are characterized by
**INT_OUT_OF_BOUNDS**
**** **7.x.1.2 Floating-point limits**
The values given in the following list shall be replaced by
implementation-defined expressions that shall be equal or
lesser in magnitude (absolute value) to those shown, with
the same sign:
-- maximum rounding error of, at least the operations,
+, -, *, and /, in terms of Units in Last Place (ULPs),
for each floating-point type,
**FLT_RND_ERR** 7.0
In general, for normal results, the rounding error, re, is
defined by:
| tr - cr | <= re * ulp(cr)
where
tr = infinitely precise true result
cr = computed result
For the full details, including difference between normals
and subnormals, see LIA-1 subclause 5.2.8 Rounding
constants.
The values given in the following list shall be replaced by
implementation-defined expressions that shall be equal or
greater in magnitude (absolute value) to those shown, with
the same sign:
-- minimum positive floating-point number, b**emin-p if
subnormalized numbers are supported, else b**emin-1,
**FLT_TRUE_MIN** 1E-37
**DBL_TRUE_MIN** 1E-37
**LDBL_TRUE_MIN** 1E-37
The level of support for subnormalized numbers is
characterized by the values
-1 indeterminable
0 not supported
1 fully supported
2 treated as zero
for the floating types float, double, long double
**FLT_SUBNORMAL**
**DBL_SUBNORMAL**
**LDBL_SUBNORMAL**
respectively.
All other negative values for ***_SUBNORMAL**
characterize implementation-defined behavior.
The values given in the following list shall be replaced by
implementation-defined expressions:
-- boolean value (0 or 1) to indicate if the corresponding
type conforms to IEC 559,
**FLT_IEC_559**
**DBL_IEC_559**
**LDBL_IEC_559**
Example 2 in is supplemented with these:
**FLT_RND_ERR** 0.5
**FLT_IEC_559** 1
**FLT_SUBNORMAL** 1
**FLT_TRUE_MIN** 1.40129846E-45
**DBL_IEC_559** 1
**DBL_SUBNORMAL** 1
**DBL_TRUE_MIN** 4.94065646E-324
*** **7.x.2 Mathematics**
Several functions are declared to provide additional
capability beyond . Most synopses specify a
function which takes one or more **double** arguments and
returns a **double** value; for each such function, there
are functions with the same name but with **f** and
**l** suffixes which are corresponding functions with
**float** and **long double** arguments and return
values.
**** **7.x.2.1 Exponential and logarithmic functions**
***** **7.x.2.1.1 The fracrep function**
**Synopsis**
**#include **
**double fracrep(double x);**
**Description**
The **fracrep** function extracts the fraction of the
model representation of **x**, as a signed normalized
fraction in the format of **x**.
**Returns**
The **fracrep** function returns the value **y**, such
that **y** is a **double** with magnitude in the
interval [1/**FLT_RADIX**, 1) or zero, and **x** equals
**y** times **FLT_RADIX** raised to the power
(**logb(x)+1.0**). The value returned for zero is 0.0.
***** **7.x.2.1.2 The ulp function**
**Synopsis**
**#include **
**double ulp(double x);**
**Description**
The **ulp** function computes the value of a Unit in the
Last Place of **x**. A domain error occurs if the
argument is zero. A range error occurs if the magnitude of
**x** is too small and subnormals are not supported.
**Returns**
The **ulp** function returns the value **FLT_RADIX**
raised to the power (**logb(x)+1-***p*). *p*
is the precision of the floating type and is one of
*_MANT_DIG.
**** **7.x.2.2 Sign function**
***** **7.x.2.2.1 The fsgn function**
**Synopsis**
**#include **
**double fsgn(double x);**
**Description**
The **fsgn** function computes the sign of a
floating-point number **x**. Positive floating-point
numbers have a sign of +1.0, negative floating-point numbers
have a sign of -1.0, and zero has a sign of 0.0.
**Returns**
The **fsgn** function returns the sign.
**** **7.x.2.3 Manipulation functions**
***** **7.x.2.3.1 The fsucc function**
**Synopsis**
**#include **
**double fsucc(double x);**
**Description**
The **fsucc** function determines the next representable
value, in the type of the function, after **x** in the
direction of +infinity. A range error occurs if **x** is
the largest positive finite number.
**Returns**
The **fsucc** function returns the smallest representable
value, of the same type, greater than **x**.
***** **7.x.2.3.2 The fpred function**
**Synopsis**
**#include **
**double fpred(double x);**
**Description**
The **fpred** function determines the next representable
value, in the type of the function, after **x** in the
direction of -infinity. A range error occurs if **x** is
the largest negative finite number.
**Returns**
The **fpred** function returns the largest representable
value, of the same type, less than **x**.
***** **7.x.2.3.3 The truncto function**
**Synopsis**
**#include **
**double truncto(double x, int n);**
**Description**
The **truncto** function truncates (rounds toward zero)
**x** to **n** digits of precision.
**Returns**
The **truncto** function returns the value for normal
numbers: sign(x) * floor(|x|/(FLT_RADIX**(expon(x)-n))) *
FLT_RADIX**(expon(x)-n) and for subnormal numbers: sign(x) *
floor(|x|/(FLT_RADIX**(emin-n))) * FLT_RADIX**(emin-n). If
**n** is less than 1, returns 0. If **n** is greater
than precision of **x**, returns **x**.
***** **7.x.2.3.4 The roundto function**
**Synopsis**
**#include **
**double roundto(double x, int n);**
**Description**
The **roundto** function rounds (rounds to biased nearest
with ties going away from zero) **x** to **n** digits
of precision. A range error may occur.
**Returns**
The **roundto** function returns the value for normal
numbers: sign(x) * floor(|x|/(FLT_RADIX**(expon(x)-n))+0.5)
* FLT_RADIX**(expon(x)-n) and for subnormal numbers: sign(x)
* floor(|x|/(FLT_RADIX**(emin-n))+0.5) * FLT_RADIX**(emin-n).
If **n** is less than 1, returns 0. If **n** is
greater than precision of **x**, returns **x**.
**** **7.x.2.4 Conversion macros**
The following subclauses provide macros that convert from
floating-point type to integral type using round to nearest
rounding. The round to nearest can be biased (ties round
away from zero) or unbiased (such as IEC 559 round to
nearest even). In the synopses in this subclause,
real-floating indicates that the argument must be an
expression of real floating type.
***** **7.x.2.4.1 The icvt macro**
**Synopsis**
**#include **
**int icvt(real-floating x);**
**Description**
The **icvt** macro rounds its argument to the nearest
integral value. If the rounded value is outside the range
of **int**, the numeric result is unspecified. A
range error may occur if the magnitude of **x**
is too large.
**Returns**
The **icvt** macro returns the rounded integral value.
***** **7.x.2.4.2 The lcvt macro**
**Synopsis**
**#include **
**long lcvt(real-floating x);**
**Description**
The **lcvt** macro is equivalent to the **icvt**
macro, except that the returned value has type **long**.
***** **7.x.2.4.3 The llcvt macro**
**Synopsis**
**#include **
**long long llcvt(real-floating x);**
**Description**
The **llcvt** macro is equivalent to the **icvt**
macro, except that the returned value has type **long
long**.
***** **7.x.2.4.4 The uicvt macro**
**Synopsis**
**#include **
**unsigned int uicvt(real-floating x);**
**Description**
The **uicvt** macro rounds its argument to the nearest
integral value. If the rounded value is outside the range
of **unsigned int**, the rounded value is wrapped modulo
(**UINT_MAX+1**).
**Returns**
The **uicvt** macro returns the rounded integral value.
***** **7.x.2.4.5 The ulcvt macro**
**Synopsis**
**#include **
**unsigned long ulcvt(real-floating x);**
**Description**
The **ulcvt** macro is equivalent to the **uicvt**
macro, except that the returned value has type **unsigned
long**.
***** **7.x.2.4.6 The ullcvt macro**
**Synopsis**
**#include **
**unsigned long long ullcvt(real-floating x);**
**Description**
The **ullcvt** macro is equivalent to the **uicvt**
macro, except that the returned value has type **unsigned
long long**.
*** **7.x.3 General utilities**
Several functions are declared to provide additional
capability beyond .
**** **7.x.3.1 The sgn function**
**Synopsis**
**#include **
**int sgn(int j);**
**Description**
The **sgn** function computes the sign of an integer
**j**. Positive integers have a sign of +1, negative
integers have a sign of -1, and zero has a sign of 0.
**Returns**
The **sgn** function returns the sign.
**** **7.x.3.2 The lsgn function**
**Synopsis**
**#include **
**long int lsgn(long int j);**
**Description**
The **lsgn** function is similar to the **sgn**
function, except that the argument and returned value each
have type **long int**.
**** **7.x.3.3 The llsgn function**
**Synopsis**
**#include **
**long long int llsgn(long long int j);**
**Description**
The **llsgn** function is similar to the **sgn**
function, except that the argument and returned value each
have type **long long int**.
**** **7.x.3.4 The modulo function**
**Synopsis**
**#include **
**int modulo(int numer, int denom);**
**Description**
The **modulo** function computes the modulus, that is,
[Ed: math equation] **numer-(floor(numer/denom)*denom)**.
If **denom** is zero, the behavior is undefined.
**Returns**
The **modulo** function returns the modulus.
**** **7.x.3.5 The lmodulo function**
**Synopsis**
**#include **
**long int lmodulo(long int numer, long int denom);**
**Description**
The **lmodulo** function is similar to the **modulo**
function, except that the arguments and returned value each
have type **long int**.
**** **7.x.3.6 The llmodulo function**
**Synopsis**
**#include **
**long long int llmodulo(long long int numer,
long long int denom);**
**Description**
The **llmodulo** function is similar to the **modulo**
function, except that the arguments and returned value each
have type **long long int**.
*** **7.x.4 Notification**
Each macro
**INT_OVERFLOW**
**INT_DIVBYZERO**
**INT_INVALID**
is defined if and only if the implementation supports the
exception by means of the functions in 7.x.4.2. The defined
macros expand to integral constant expressions whose values
are distinct powers of 2.
The macro
**INT_ALL_EXCEPT**
is simply the bitwise OR of all integer exception macros
defined by the implementation.
These next three macros describe what notifications happen
for conversions of values from floating-point types to
integral types for some specific values.
-- value to indicate what notification happens for
NaNs,
**FP2INT_OF_NAN**
It should be INT_INVALID, but may be FE_INVALID or another
exception indicator macro.
-- value to indicate what notification happens for
infinities,
**FP2INT_OF_INF**
It should be INT_INVALID, but may be FE_INVALID or another
exception indicator macro.
-- value to indicate what notification happens for
out-of-bounds integral values,
**FP2INT_OF_LARGE**
It should be INT_OVERFLOW, but may be FE_INVALID or another
exception indicator macro, when INT_OUT_OF_BOUNDS is 2
(notify).
The FP2INT_OF_LARGE macro shall be 0 (meaning no exception)
when INT_OUT_OF_BOUNDS is 1 (wrap).
The macro
**DISTINGUISH_INT_DIV_BY_ZERO**
has a boolean value (0 or 1) to indicate if 0/0 can be
distinguished from non-zero/zero. If this is true,
then 0/0 will notify as invalid, else, as divbyzero.
The macro
**DISTINGUISH_FP_DIV_BY_ZERO**
has a boolean value (0 or 1) to indicate if 0.0/0.0 can be
distinguished from finite non-zero/zero. If this is true,
then 0.0/0.0 will notify as invalid, else, as divbyzero.
**** **7.x.4.1 The LIA_NOTIFY pragma and macro**
***** **7.x.4.1.1 The LIA_NOTIFY pragma**
**Synopsis**
**#include **
**#pragma STDC LIA_NOTIFY { UNDEF | IGNORE | FLAGS | TRAP }**
**Description**
The LIA_NOTIFY pragma provides a means to inform the
implementation which notification mechanism is to be
used[footnote]. The pragma can occur either outside
external declarations or preceding all explicit declarations
and statements inside a compound statement. When outside
external declarations, the pragma takes effect from its
occurrence until another LIA_NOTIFY pragma is encountered,
or until the end of the translation unit. When inside a
compound statement, the pragma takes effect from its
occurrence until another LIA_NOTIFY pragma is encountered
(within a nested compound statement), or until the end of
the compound statement; at the end of a compound statement
the state for the pragma is restored to its condition just
before the compound statement. The effect of this pragma in
any other context is undefined. If part of a program tests
flags or runs under non-default mode settings, but was
translated with the state for the LIA_NOTIFY pragma UNDEF,
then the behavior of that program is undefined.
UNDEF shall cause notifications to be undefined behaviour.
This matches C89/C95.
IGNORE shall cause notifications to be ignored. Traps shall
not be taken. It is implementation defined if status flags
will be set. An implementation defined continuation value
will be used in place of the failing arithmetic operation.
This causes the final check of the status flags at program
termination to be suppressed. This allows the optimizations
mentioned in the subsection on "FENV_ACCESS off" to be done.
FLAGS shall cause notifications to set a status flag and
proceed with a continuation value in place of the arithmetic
failure. It is implementation defined if the final check of
some status flags at program termination will be performed.
TRAP shall cause notifications to trap. It is
implementation defined if a trap shall be turned into a
raise of some signal, or result in program termination.
Until is included, the default state for the
pragma shall be UNDEF. Once is included, the
default state for the pragma is implementation-defined and
shall be one of FLAGS, TRAP, (or DYNAMIC if supported).
It is implementation defined if the different translation
units that comprise a program are translated with different
LIA_NOTIFY states.
It is implementation defined which of **INT_OVERFLOW**,
**INT_DIVBYZERO**, **INT_INVALID**, **FE_INEXACT**,
**FE_UNDERFLOW**, **FE_OVERFLOW**,
**FE_DIVBYZERO**, and **FE_INVALID** are defined.
Those defined determine the set of notifications being
checked.
[footnote]Notification is the process by which a program is
informed that an arithmetic operation cannot be performed.
***** **7.x.4.1.2 The LIA_NOTIFY macro**
The macro
**LIA_NOTIFY**
has one of these values (with corresponding meaning)
0 Undefined, like C89/C95
1 Notifications are ignored
2 All notifications will set flags
3 All notifications will trap
4 Program switches between flags and traps at runtime
to indicate the current way notifications are being handled.
That is, the macro tracks the state of the LIA_NOTIFY
pragma.
**** **7.x.4.2 Exception flags**
The following functions provide access to the integer
exception flags. They support the basic abstraction of
flags that are either set or clear. The **int** input
argument for the functions represents a subset of integer
exceptions, and can be constructed by bitwise ORs of the
integer exception macros, for example (INT_DIVBYZERO |
INT_INVALID). For other argument values the behavior of
these functions is undefined.
***** **7.x.4.2.1 The ieclearexcept function**
**Synopsis**
**#include **
**void ieclearexcept(int excepts);**
**Description**
The ieclearexcept function clears the supported integer
exceptions represented by its argument.
***** **7.x.4.2.2 The ieraiseexcept function**
**Synopsis**
**#include **
**void ieraiseexcept(int excepts);**
**Description**
The ieraiseexcept function raises the supported integer
exceptions represented by its argument. The order in which
these exceptions are raised is unspecified.
***** **7.x.4.2.3 The ietestexcept function**
**Synopsis**
**#include **
**int ietestexcept(int excepts);**
**Description**
The ietestexcept function determines which of a specified
subset of the integer exception flags are currently set.
The **excepts** argument specifies the integer exception
flags to be queried.[footnote]
[footnote]. This mechanism allows testing several
exceptions with just one function call.
**Returns**
The ietestexcept function returns the value of the bitwise
OR of the integer exception macros corresponding to the
currently set exceptions included in **excepts**.
* -- Add to 7.? Type-generic math :
after all occurances of
** -- Add to 7.?.1 Type-generic macros
*** -- Add to the list of real (but not complex) functions that
starts atan2, exp2:
**fracrep**
**ulp**
**fsgn**
**fsucc**
**fpred**
**truncto**
**roundto**
* -- Add to Annex D Library summary
** -- Add new subclause: **D.x Notification and additional utilities **
*** -- Add new subclause: **D.x.1 Limits**
**** -- Add new subclause: **D.x.1.1 Integral limits**
**INT_OUT_OF_BOUNDS**
**** -- Add new subclause: **D.x.1.2 Floating-point limits**
**FLT_RND_ERR**
**FLT_TRUE_MIN**
**DBL_TRUE_MIN**
**LDBL_TRUE_MIN**
**FLT_SUBNORMAL**
**DBL_SUBNORMAL**
**LDBL_SUBNORMAL**
**FLT_IEC_559**
**DBL_IEC_559**
**LDBL_IEC_559**
*** -- Add new subclause: **D.x.2 Mathematics**
[Note to editor: If we need to include the float and long
double versions, here, and in and ,
please add them.]
**double fracrep(double x);**
**double ulp(double x);**
**double fsgn(double x);**
**double fsucc(double x);**
**double fpred(double x);**
**double truncto(double x, int n);**
**double roundto(double x, int n);**
*** -- Add new subclause: **D.x.3 General utilities**
**int icvt(real-floating x);**
**long lcvt(real-floating x);**
**long long llcvt(real-floating x);**
**unsigned int uicvt(real-floating x);**
**unsigned long ulcvt(real-floating x);**
**unsigned long long ullcvt(real-floating x);**
**int sgn(int j);**
**long int lsgn(long int j);**
**long long int llsgn(long long int j);**
**int modulo(int numer, int denom);**
**long int lmodulo(long int numer, long int denom);**
**long long int llmodulo(long long int numer,
long long int denom);**
*** -- Add new subclause: **D.x.4 Notification**
**INT_OVERFLOW**
**INT_DIVBYZERO**
**INT_INVALID**
**INT_ALL_EXCEPT**
**FP2INT_OF_NAN**
**FP2INT_OF_INF**
**FP2INT_OF_LARGE**
**DISTINGUISH_INT_DIV_BY_ZERO**
**DISTINGUISH_FP_DIV_BY_ZERO**
**#pragma STDC LIA_NOTIFY { UNDEF | IGNORE | FLAGS | TRAP }**
**LIA_NOTIFY**
**void ieclearexcept(int excepts);**
**void ieraiseexcept(int excepts);**
**int ietestexcept(int excepts);**
* -- Add to Annex F IEC 559 Floating-Point Arithmetic:
** -- Add new subclause F.10 :
*** F.10.1 Exponential and logarithmic functions
**** F.10.1.1 The fracrep function
fracrep(-0.0) returns -0.0
fracrep(+/-INFINITY) returns +/-INFINITY
**** F.10.1.2 The ulp function
ulp(-0.0) returns a NaN and raises the invalid
exception.
ulp(+/-INFINITY) returns a NaN and raises the invalid
exception.
ulp(1.0) returns DBL_EPSILON.
*** F.10.2 Sign function
**** F.10.2.1 The fsgn function
fsgn(-0.0) returns -0.0
fsgn(+INFINITY) returns +1.0
fsgn(-INFINITY) returns -1.0
fsgn(NaN) returns the same NaN.
*** F.10.3 Manipulation functions
**** F.10.3.1 The fsucc function
fsucc(-0.0) returns +DBL_TRUE_MIN
fsucc(+INFINITY) returns +INFINITY
fsucc(+DBL_MAX) returns +INFINITY and raises overflow.
**** F.10.3.2 The fpred function
fpred(-0.0) returns -DBL_TRUE_MIN
fpred(-INFINITY) returns -INFINITY
fpred(-DBL_MAX) returns -INFINITY and raises overflow.
**** F.10.3.3 The truncto function
truncto(-0.0, n) returns -0.0 for any n.
truncto(+/-INFINITY, n) returns +/-INFINITY for any n.
truncto(NaN, n) returns the same NaN for any n.
**** F.10.3.4 The roundto function
roundto(-0.0, n) returns -0.0 for any n.
roundto(+/-INFINITY, n) returns +/-INFINITY for any n.
roundto(NaN, n) returns the same NaN for any n.
*** F.10.4 Conversion macros
**** F.10.4.1 The icvt macro
icvt(NaN) returns an unspecified value and raises
FP2INT_OF_NAN.
icvt(+/-INFINITY) returns an unspecified value and
raises FP2INT_OF_INF.
**** F.10.4.2 The lcvt macro
lcvt(NaN) returns an unspecified value and raises
FP2INT_OF_NAN.
lcvt(+/-INFINITY) returns an unspecified value and
raises FP2INT_OF_INF.
**** F.10.4.3 The llcvt macro
llcvt(NaN) returns an unspecified value and raises
FP2INT_OF_NAN.
llcvt(+/-INFINITY) returns an unspecified value and
raises FP2INT_OF_INF.
**** F.10.4.4 The uicvt macro
uicvt(NaN) returns an unspecified value and raises
FP2INT_OF_NAN.
uicvt(+/-INFINITY) returns an unspecified value and
raises FP2INT_OF_INF.
**** F.10.4.5 The ulcvt macro
ulcvt(NaN) returns an unspecified value and raises
FP2INT_OF_NAN.
ulcvt(+/-INFINITY) returns an unspecified value and
raises FP2INT_OF_INF.
**** F.10.4.6 The ullcvt macro
ullcvt(NaN) returns an unspecified value and raises
FP2INT_OF_NAN.
ullcvt(+/-INFINITY) returns an unspecified value and
raises FP2INT_OF_INF.