/*
* Copyright (c) 2005-2006 Institute for System Programming
* Russian Academy of Sciences
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Portions of this text are reprinted and reproduced in electronic form
* from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology
* -- Portable Operating System Interface (POSIX), The Open Group Base
* Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of
* Electrical and Electronics Engineers, Inc and The Open Group. In the
* event of any discrepancy between this version and the original IEEE and
* The Open Group Standard, the original IEEE and The Open Group Standard
* is the referee document. The original Standard can be obtained online at
* http://www.opengroup.org/unix/online.html.
*/
/*
* Portions of this text are reprinted and reproduced in electronic form
* from the Single UNIX Specification Version 2, Copyright (C) 1997 by The Open
* Group. In the event of any discrepancy between this version and the original
* document from the Open Group, the Open Group document is the referee document.
* The original document can be obtained online at http://www.unix.org/version2/online.html.
*/
#include "util/float/float_model.seh"
#include "util/float/float_config.h"
#pragma SEC subsystem float "util.float"
/*
The group of functions 'util.float' consists of:
__finite [1]
__finitef [1]
__finitel [1]
__fpclassify [3]
__fpclassifyf [3]
__isinf [2]
__isinff [2]
__isinfl [2]
__isnan [2]
__isnanf [2]
__isnanl [2]
__signbit [1]
__signbitf [1]
finite [4]
finitef [1]
finitel [1]
frexp [2]
frexpf [2]
frexpl [2]
ilogb [2]
ilogbf [2]
ilogbl [2]
ldexp [2]
ldexpf [2]
ldexpl [2]
logb [2]
logbf [2]
logbl [2]
nextafter [2]
nextafterf [2]
nextafterl [2]
nexttoward [2]
nexttowardf [2]
nexttowardl [2]
scalb [2]
scalbf [1]
scalbl [1]
scalbln [2]
scalblnf [2]
scalblnl [2]
scalbn [2]
scalbnf [2]
scalbnl [2]
significand [1]
significandf [1]
significandl [1]
*/
/********************************************************************/
/** Interface Functions **/
/********************************************************************/
/****
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
isfinite - test for finite value
SYNOPSIS
#include <math.h>
int isfinite(real-floating x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. The isfinite() macro shall determine whether its argument has a
finite value (zero, subnormal, or normal, and not infinite or NaN). First, an
argument represented in a format wider than its semantic type is converted to
its semantic type. Then determination is based on the type of the argument.
RETURN VALUE
The isfinite() macro shall return a non-zero value if and only if its argument
has a finite value.
ERRORS
No errors are defined.
****/
//This specification refers to: __finitef, __finite, __finitel
specification
IntT __finite_spec(CallContext context, Unifloat* x)
{
char type[3][50] = {"__finitef", "__finite", "__finitel"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return x!=NULL;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
return {Normal_arg, "The argument is finite"};
}
post
{
/*
* The isfinite() macro shall determine whether its argument has a
* finite value (zero, subnormal, or normal, and not infinite or NaN).
*
* The isfinite() macro shall return a non-zero value if and only if
* its argument has a finite value.
*/
REQ("__finite.isfinite.01;__finitef.isfinite.01;__finitel.isfinite.01;"
"__finite.isfinite.02;__finitef.isfinite.02;__finitel.isfinite.02",
"Function should return a non-sero if and only if its argument"
" is finite",
(isNormal_Unifloat(x)&&(__finite_spec != 0)) ||
(!isNormal_Unifloat(x)&&(__finite_spec == 0)));
return true;
}
FILTER_CLEAN;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__fpclassify -- Classify real floating type
SYNOPSIS
int __fpclassify(double arg);
DESCRIPTION
__fpclassify() has the same specification as fpclassify() in ISO POSIX
(2003), except that the argument type for __fpclassify() is known to be
double.
__fpclassify() is not in the source standard; it is only in the binary
standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__fpclassifyf -- Classify real floating type
SYNOPSIS
int __fpclassifyf(float arg);
DESCRIPTION
__fpclassifyf() has the same specification as fpclassifyf() in ISO POSIX
(2003), except that the argument type for __fpclassifyf() is known to be
float.
__fpclassifyf() is not in the source standard; it is only in the binary
standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
fpclassify - classify real floating type
SYNOPSIS
#include <math.h>
int fpclassify(real-floating x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. The fpclassify() macro shall classify its argument value as
NaN, infinite, normal, subnormal, zero, or into another implementation-defined
category. First, an argument represented in a format wider than its semantic
type is converted to its semantic type. Then classification is based on the
type of the argument.
RETURN VALUE
The fpclassify() macro shall return the value of the number classification
macro appropriate to the value of its argument.
ERRORS
No errors are defined.
*/
//This specification refers to: __fpclassifyf, __fpclassify
specification
IntT __fpclassify_spec(CallContext context, Unifloat* x)
{
char type[2][50] = {"__fpclassifyf", "__fpclassify"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return x!=NULL;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
if (isZero_Unifloat(x))
return {Zero_arg, "The argument is zero"};
else
if (isUnderflow_Unifloat(x))
return {Subnormal, "The argument is subnormal"};
else
return {Normal_arg, "The argument is normal"};
}
post
{
IntT model_res = __fpclassify_model(x);
/*
* The fpclassify() macro shall classify its argument value as NaN,
* infinite, normal, subnormal, zero, or into another implementation-
* defined category.
*
* The fpclassify() macro shall return the value of the number
* classification macro appropriate to the value of its argument.
*/
/* [ constants of kinds of floating-point numbers:
FP_NAN = 0
FP_INFINITE = 1
FP_ZERO = 2
FP_SUBNORMAL = 3
FP_NORMAL = 4 ] */
REQ("__fpclassify.fpclassify.01;__fpclassifyf.fpclassify.01;"
"__fpclassify.fpclassify.02;__fpclassifyf.fpclassify.02",
"shall return the value of the number classification macro"
" appropriate to the value of its argument",
model_res == __fpclassify_spec);
/*
* __fpclassify() has the same specification as fpclassify() in ISO POSIX (2003),
* except that the argument type for __fpclassify() is known to be double.
*/
REQ( "__fpclassify.30",
"__fpclassify() has the same specification as fpclassify() except that the argument type for __fpclassify() is known to be double",
GENERAL_REQ( "__fpclassify.fpclassify.*" )
);
/*
* __fpclassifyf() has the same specification as fpclassifyf() in ISO
* POSIX (2003), except that the argument type for __fpclassifyf() is known to be
* float.
*/
REQ( "__fpclassifyf.30",
"__fpclassifyf() has the same specification as fpclassifyf() except that the argument type for __fpclassifyf() is known to be float",
GENERAL_REQ( "__fpclassifyf.fpclassify.*" )
);
return true;
}
FILTER_CLEAN;
}
IntT __fpclassify_model(Unifloat* x)
{
if (isNan_Unifloat(x))
return 0;
if (isInfinity_Unifloat(x))
return 1;
if (isZero_Unifloat(x))
return 2;
if (isUnderflow_Unifloat(x))
return 3;
return 4;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__isinf -- test for infinity
SYNOPSIS
int __isinf(double arg);
DESCRIPTION
__isinf() has the same specification as isinf() in ISO POSIX (2003), except
that the argument type for __isinf() is known to be double.
__isinf() is not in the source standard; it is only in the binary standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__isinff -- test for infinity
SYNOPSIS
int __isinff(float arg);
DESCRIPTION
__isinff() has the same specification as isinf() in ISO POSIX (2003) except
that the argument type for __isinff() is known to be float.
__isinff() is not in the source standard; it is only in the binary standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__isinfl -- test for infinity
SYNOPSIS
int __isinfl(long double arg);
DESCRIPTION
__isinfl() has the same specification as isinf() in the ISO POSIX (2003),
except that the argument type for __isinfl() is known to be long double.
__isinfl() is not in the source standard; it is only in the binary standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
isinf - test for infinity
SYNOPSIS
#include <math.h>
int isinf(real-floating x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. The isinf() macro shall determine whether its argument value is
an infinity (positive or negative). First, an argument represented in a format
wider than its semantic type is converted to its semantic type. Then
determination is based on the type of the argument.
RETURN VALUE
The isinf() macro shall return a non-zero value if and only if its argument has
an infinite value.
ERRORS
No errors are defined.
*/
//This specification refers to: __isinff, __isinf, __isinfl
specification
IntT __isinf_spec(CallContext context, Unifloat* x)
{
char type[3][50] = {"__isinff", "__isinf", "__isinfl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
return {Normal_arg, "The argument is finite"};
}
post
{
/*
* The isinf() macro shall determine whether its argument value is an
* infinity (positive or negative).
*
* The isinf() macro shall return a non-zero value if and only if its
* argument has an infinite value.
*/
REQ("__isinf.isinf.01;__isinff.isinf.01;__isinfl.isinf.01;"
"__isinf.isinf.02;__isinff.isinf.02;__isinfl.isinf.02",
"It shall return a non-zero value if and only if its"
" argument has an infinite value",
(isInfinity_Unifloat(x) && (__isinf_spec !=0)) ||
(!isInfinity_Unifloat(x) && (__isinf_spec == 0)));
/*
* __isinf() has the same specification as isinf() in ISO POSIX (2003), except
* that the argument type for __isinf() is known to be double.
*/
REQ( "__isinf.30",
"__isinf() has the same specification as isinf(), except that the argument type for __isinf() is known to be double",
GENERAL_REQ( "__isinf.isinf.*" )
);
/*
* __isinff() has the same specification as isinf() in ISO POSIX (2003) except
* that the argument type for __isinff() is known to be float.
*/
REQ( "__isinff.30",
"__isinff() has the same specification as isinf(), except that the argument type for __isinf() is known to be float",
GENERAL_REQ( "__isinff.isinf.*" )
);
/*
* __isinfl() has the same specification as isinf() in the ISO POSIX (2003),
* except that the argument type for __isinfl() is known to be long double.
*/
REQ("__isinfl.30",
"__isinfl() has the same specification as isinf(), except that the argument type for __isinf() is known to be long double",
GENERAL_REQ( "__isinfl.isinf.*" )
);
return true;
}
FILTER_CLEAN;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__isnan -- test for infinity
SYNOPSIS
int __isnan(double arg);
DESCRIPTION
__isnan() has the same specification as isnan() in ISO POSIX (2003), except
that the argument type for __isnan() is known to be double.
__isnan() is not in the source standard; it is only in the binary standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__isnanf -- test for infinity
SYNOPSIS
int __isnanf(float arg);
DESCRIPTION
__isnanf() has the same specification as isnan() in ISO POSIX (2003), except
that the argument type for __isnanf() is known to be float.
__isnanf() is not in the source standard; it is only in the binary standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
NAME
__isnanl -- test for infinity
SYNOPSIS
int __isnanl(long double arg);
DESCRIPTION
__isnanl() has the same specification as isnan() in ISO POSIX (2003), except
that the argument type for __isnanl() is known to be long double.
__isnanl() is not in the source standard; it is only in the binary standard.
*/
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
isnan - test for a NaN
SYNOPSIS
#include <math.h>
int isnan(real-floating x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. The isnan() macro shall determine whether its argument value is
a NaN. First, an argument represented in a format wider than its semantic type
is converted to its semantic type. Then determination is based on the type of
the argument.
RETURN VALUE
The isnan() macro shall return a non-zero value if and only if its argument has
a NaN value.
ERRORS
No errors are defined.
*/
//This specification refers to: __isnanf, __isnan, __isnanl
specification
IntT __isnan_spec(CallContext context, Unifloat* x)
{
char type[3][50] = {"__isnanf", "__isnan", "__isnanl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
return {Normal_arg, "The argument is finite"};
}
post
{
/*
* The isnan() macro shall determine whether its argument value is a
* NaN.
*
* The isnan() macro shall return a non-zero value if and only if its argument has
* a NaN value.
*/
#if NAN_SUPPORT == 1
REQ("__isnan.isnan.01;__isnanf.isnan.01;__isnanl.isnan.01;"
"__isnan.isnan.02;__isnanf.isnan.02;__isnanl.isnan.02",
"It shall return a non-zero value if and only if its"
" argument has a NaN value",
(isNan_Unifloat(x) && (__isnan_spec !=0)) ||
(!isNan_Unifloat(x) && (__isnan_spec == 0)));
#endif
/*
* __isnan() has the same specification as isnan() in ISO POSIX (2003), except
* that the argument type for __isnan() is known to be double.
*/
REQ( "__isnan.30",
"__isnan() has the same specification as isnan(), except that the argument type for __isnan() is known to be double",
GENERAL_REQ( "__isnan.isnan.*" )
);
/*
* __isnanf() has the same specification as isnan() in ISO POSIX (2003), except
* that the argument type for __isnanf() is known to be float.
*/
REQ( "__isnanf.30",
"__isnanf() has the same specification as isnan(), except that the argument type for __isnan() is known to be float",
GENERAL_REQ( "__isnanf.isnan.*" )
);
/*
* __isnanl() has the same specification as isnan() in ISO POSIX (2003), except
* that the argument type for __isnanl() is known to be long double.
*/
REQ( "__isnanl.30",
"__isnan;() has the same specification as isnan(), except that the argument type for __isnan() is known to be long double",
GENERAL_REQ( "__isnan;.isnan.*" )
);
return true;
}
FILTER_CLEAN;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
signbit - test sign
SYNOPSIS
#include <math.h>
int signbit(real-floating x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. The signbit() macro shall determine whether the sign of its
argument value is negative. NaNs, zeros, and infinities have a sign bit.
RETURN VALUE
The signbit() macro shall return a non-zero value if and only if the sign of
its argument value is negative.
ERRORS
No errors are defined.*/
//This specification refers to: __signbitf, __signbit
specification
IntT __signbit_spec(CallContext context, Unifloat* x, IntT *ExistFunction)
{
char type[2][50] = {"__signbitf", "__signbit"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (x->sign == 1)
return {Positive, "The argument is positive"};
else
return {Negative, "The argument is negative"};
}
post
{
/*
* The signbit() macro shall determine whether the sign of its
* argument value is negative.
*
* The signbit() macro shall return a non-zero value if and only if
* the sign of its argument value is negative.
*/
REQ("__signbit.signbit.01;__signbitf.signbit.01;"
"__signbit.signbit.02;__signbitf.signbit.02",
"It shall return a non-zero value if and only if "
" the sign of its argument value is negative",
(x->sign == 1) && (__signbit_spec == 0) ||
(x->sign == -1) && (__signbit_spec != 0));
return true;
}
FILTER_CLEAN;
}
/****
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
isfinite - test for finite value
SYNOPSIS
#include <math.h>
int isfinite(real-floating x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. The isfinite() macro shall determine whether its argument has a
finite value (zero, subnormal, or normal, and not infinite or NaN). First, an
argument represented in a format wider than its semantic type is converted to
its semantic type. Then determination is based on the type of the argument.
RETURN VALUE
The isfinite() macro shall return a non-zero value if and only if its argument
has a finite value.
ERRORS
No errors are defined.
****/
//This specification refers to: finitef, finite, finitel
specification
IntT finite_spec(CallContext context, Unifloat* x)
{
char type[3][50] = {"finitef", "finite", "finitel"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
return {Normal_arg, "The argument is finite"};
}
post
{
/*
* The isfinite() macro shall determine whether its argument has a
* finite value (zero, subnormal, or normal, and not infinite or NaN).
*
* The isfinite() macro shall return a non-zero value if and only if
* its argument has a finite value.
*/
REQ("finite.isfinite.01;finitef.isfinite.01;finitel.isfinite.01;"
"finite.isfinite.02;finitef.isfinite.02;finitel.isfinite.02",
"Function should return a non-sero if and only if its argument"
" is finite", (isNormal_Unifloat(x)&&(finite_spec != 0)) ||
(!isNormal_Unifloat(x)&&(finite_spec == 0)));
return true;
}
FILTER_CLEAN;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
frexp, frexpf, frexpl - extract mantissa and exponent from a double precision
number
SYNOPSIS
#include <math.h>
double frexp(double num, int *exp);
float frexpf(float num, int *exp);
long double frexpl(long double num, int *exp);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. These functions shall break a floating-point number num into a
normalized fraction and an integral power of 2. The integer exponent shall be
stored in the int object pointed to by exp.
RETURN VALUE
For finite arguments, these functions shall return the value x, such that x has
a magnitude in the interval [1/2,1) or 0, and num equals x times 2 raised to the
power *exp.
[MX] If num is NaN, a NaN shall be returned, and the value of *exp is
unspecified.
If num is 0, 0 shall be returned, and the value of *exp shall be 0.
If num is Inf, num shall be returned, and the value of *exp is unspecified.
ERRORS
No errors are defined.
*/
//This specification refers to: frexpf, frexp, frexpl
specification
Unifloat* frexp_spec(CallContext context, Unifloat* x, IntT* exp)
{
char type[3][50] = {"frexpf", "frexp", "frexpl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
if (isZero_Unifloat(x))
return {Null_arg, "The argument is zero"};
else
return {Normal_arg, "The argument is finite, non-zero"};
}
post
{
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
IntT model_exp;
/*[Calculate model function]*/
Unifloat* model_res = frexp_model(x, &model_exp);
/* [frexp_spec has PRECISION numbers in mantissa. It should be
* decreased to mantissa in appropriate type]*/
round_Unifloat(frexp_spec, mant[x->type]);
/*
* These functions shall break a floating-point number num into a
* normalized fraction and an integral power of 2.
*
* For finite arguments, these functions shall return the value x,
* such that x has a magnitude in the interval [1/2,1) or 0,
* and num equals x times 2 raised to the power *exp.
*/
REQ("frexp.01.02;frexpf.01.02;frexpl.01.02",
"It shall return the value x, such that"
"num equals x times 2 raised to the power *exp.",
(compare_Unifloat(model_res, frexp_spec) == 0) &&
(model_exp == *exp) );
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x))
{
/*
* [MX] If num is NaN, a NaN shall be returned, and the value of *exp
* is unspecified.
*/
REQ("frexp.02;frexpf.02;frexpl.02",
"If num is NaN, a NaN shall be returned",
isNan_Unifloat(frexp_spec));
}
#endif
if (isZero_Unifloat(x))
{
/*
* If num is 0, 0 shall be returned, and the value of *exp shall be 0
*/
REQ("frexp.03;frexpf.03;frexpl.03",
"If num is 0, 0 shall be returned,"
" and the value of *exp shall be 0",
isZero_Unifloat(frexp_spec) && (*exp == 0));
}
if (isInfinity_Unifloat(x))
{
/*
* If num is Inf, num shall be returned, and the value of *exp is
* unspecified.
*/
REQ("frexp.04;frexpf.04;frexpl.04",
"If num is Inf, num shall be returned",
compare_Unifloat(x, frexp_spec) == 0 );
}
return true;
}
FILTER_CLEAN;
}
Unifloat* frexp_model(Unifloat* x, IntT* exp)
{
Unifloat* res = clone(x);
Unifloat* One = createOne_Unifloat(x->type);
*exp = 0;
if (isNan_Unifloat(x) || isInfinity_Unifloat(x))
return res;
if (!isZero_Unifloat(x))
*exp = x->exp;
res->exp = 0;
return res;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
ilogb, ilogbf, ilogbl - return an unbiased exponent
SYNOPSIS
#include <math.h>
int ilogb(double x);
int ilogbf(float x);
int ilogbl(long double x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. These functions shall return the exponent part of their
argument x. Formally, the return value is the integral part of logr|x| as a
signed integral value, for non-zero x, where r is the radix of the machine's
floating-point arithmetic, which is the value of FLT_RADIX defined in <float.
h>.
An application wishing to check for error situations should set errno to zero
and call feclearexcept(FE_ALL_EXCEPT) before calling these functions. On
return, if errno is non-zero or fetestexcept (FE_INVALID | FE_DIVBYZERO |
FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred.
RETURN VALUE
Upon successful completion, these functions shall return the exponent part of x
as a signed integer value. They are equivalent to calling the corresponding
logb() function and casting the returned value to type int.
If x is 0, [XSI] a domain error shall occur, and the value FP_ILOGB0 shall be
returned.
If x is Inf, [XSI] a domain error shall occur, and the value {INT_MAX} shall
be returned.
If x is a NaN, [XSI] a domain error shall occur, and the value FP_ILOGBNAN
shall be returned.
[XSI] If the correct value is greater than {INT_MAX}, {INT_MAX} shall be
returned and a domain error shall occur.
If the correct value is less than {INT_MIN}, {INT_MIN} shall be returned and a
domain error shall occur.
ERRORS
These functions shall fail if:
Domain Error [XSI] The x argument is zero, NaN, or Inf, or the correct value
is not representable as an integer.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [EDOM]. If the integer expression (math_errhandling &
MATH_ERREXCEPT) is non-zero, then the invalid floating-point exception shall be
raised.
*/
//This specification refers to: ilogbf, ilogb, ilogbl
specification
IntT ilogb_spec(CallContext context, Unifloat* x, ErrorCode* errno)
{
char type[3][50] = {"ilogbf", "ilogb", "ilogbl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
if (isZero_Unifloat(x))
return {Zero_arg, "The argument is zero"};
else
if (isUnderflow_Unifloat(x))
return {Subnormal, "The argument is subnormal"};
else
return {Normal_arg, "The argument is normal"};
}
post
{
LongT model_res = ilogb_model(x);
if (isZero_Unifloat(x))
{
/*
* If x is 0, [XSI] a domain error shall occur, and the value
* FP_ILOGB0 shall be returned.
*/
REQ("ilogb.05;ilogbf.05;ilogbl.05",
"If x is 0, FP_ILOGB0 shall be returned",
ilogb_spec == SUT_FP_ILOGB0);
}
if (isInfinity_Unifloat(x))
{
/*
* If x is Inf, [XSI] a domain error shall occur, and the value {
* INT_MAX} shall be returned.
*/
REQ("ilogb.06;ilogbf.06;ilogbl.06",
"If x is Inf, {INT_MAX} shall be returned",
ilogb_spec == SUT_INT_MAX);
}
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x))
{
/*
* If x is a NaN, [XSI] a domain error shall occur, and the value
* FP_ILOGBNAN shall be returned.
*/
REQ("ilogb.07;ilogbf.07;ilogbl.07",
"If x is a NaN, FP_ILOGBNAN shall be returned",
ilogb_spec == SUT_FP_ILOGBNAN);
}
#endif
if (!isNan_Unifloat(x) && !isInfinity_Unifloat(x) && !isZero_Unifloat(x))
{
if (model_res > SUT_INT_MAX)
{
/*
* [XSI] If the correct value is greater than {INT_MAX}, {INT_MAX}
* shall be returned and a domain error shall occur.
*/
REQ("ilogb.08;ilogbf.08;ilogbl.08",
"If the correct value is greater than {INT_MAX},"
"{INT_MAX} shall be returned",
ilogb_spec == SUT_INT_MAX);
}
if (model_res < SUT_INT_MIN)
{
/*
* If the correct value is less than {INT_MIN}, {INT_MIN} shall be
* returned and a domain error shall occur.
*/
REQ("ilogb.09;ilogbf.09;ilogbl.09",
"If the correct value is less than {INT_MIN},"
" {INT_MIN} shall be returned",
ilogb_spec == SUT_INT_MIN);
}
}
/*
* These functions shall fail if:
*
* Domain Error [XSI] The x argument is zero, NaN, or Inf, or the
* correct value is not representable as an integer.
*/
ERROR_BEGIN(POSIX_ILOGB,
"ilogb.10.01.01;ilogbf.10.01.01;ilogbl.10.01.01", *errno, *errno)
/*
* These functions shall fail if:
*
* Domain Error [XSI] The x argument is zero, NaN, or Inf, or the
* correct value is not representable as an integer.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
-zero, then
* errno shall be set to [EDOM].
*/
ERROR_SHALL(POSIX_ILOGB, EDOM,
"ilogb.10.01.01;ilogbf.10.01.01;ilogbl.10.01.01",
isZero_Unifloat(x) || isNan_Unifloat(x) || isInfinity_Unifloat(x) )
ERROR_END()
/*
* Upon successful completion, these functions shall return the
* exponent part of x as a signed integer value.
*/
REQ("ilogb.04;ilogbf.04;ilogbl.04",
"It shall return the exponent part of x",
model_res == ilogb_spec);
return true;
}
FILTER_CLEAN;
}
LongT ilogb_model(Unifloat* x)
{
if (isZero_Unifloat(x))
return SUT_FP_ILOGB0;
if (isInfinity_Unifloat(x))
return SUT_INT_MAX;
if (isNan_Unifloat(x))
return SUT_FP_ILOGBNAN;
return x->exp - 1;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
--------------------------------------------------------------------------------
NAME
ldexp, ldexpf, ldexpl - load exponent of a floating-point number
SYNOPSIS
#include <math.h>
double ldexp(double x, int exp);
float ldexpf(float x, int exp);
long double ldexpl(long double x, int exp);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. These functions shall compute the quantity x * 2 exp.
An application wishing to check for error situations should set errno to zero
and call feclearexcept(FE_ALL_EXCEPT) before calling these functions. On
return, if errno is non-zero or fetestexcept(FE_INVALID | FE_DIVBYZERO |
FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred.
RETURN VALUE
Upon successful completion, these functions shall return x multiplied by 2,
raised to the power exp.
If these functions would cause overflow, a range error shall occur and ldexp(),
ldexpf(), and ldexpl() shall return HUGE_VAL, HUGE_VALF, and HUGE_VALL
(according to the sign of x), respectively.
If the correct value would cause underflow, and is not representable, a range
error may occur, and [MX] either 0.0 (if supported), or an implementation-
defined value shall be returned.
[MX] If x is NaN, a NaN shall be returned.
If x is 0 or Inf, x shall be returned.
If exp is 0, x shall be returned.
If the correct value would cause underflow, and is representable, a range error
may occur and the correct value shall be returned.
ERRORS
These functions shall fail if:
Range Error The result overflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the overflow floating-point exception
shall be raised.
These functions may fail if:
Range Error The result underflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the underflow floating-point exception
shall be raised.
*/
//This specification refers to: ldexpf, ldexp, ldexpl
specification
Unifloat* ldexp_spec(CallContext context, Unifloat* x, IntT exp, ErrorCode* errno)
{
CharT * filter[] = { (CharT *)"ldexpf", (CharT *)"ldexp", (CharT *)"ldexpl" };
FILTER(filter[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if(isNan_Unifloat(x))
return {x_NaN, "x is NaN"};
else
if(isInfinity_Unifloat(x))
return {x_Inf, "x is Infinity"};
else
if(isZero_Unifloat(x))
return {x_Zero, "x is Zero"};
else
if(
(x->type == UniFloatT && x->exp + exp < min_FloatT->exp)
|| (x->type == UniDoubleT && x->exp + exp < min_DoubleT->exp)
|| (x->type == UniLongDoubleT && x->exp + exp < min_LongDoubleT->exp)
)
return {x_Under, "x cause underflow"};
else
if(
(x->type == UniFloatT && x->exp + exp > max_FloatT->exp)
|| (x->type == UniDoubleT && x->exp + exp > max_DoubleT->exp)
|| (x->type == UniLongDoubleT && x->exp + exp > max_LongDoubleT->exp)
)
return {x_Over, "x cause overflow"};
else
if(exp == 0)
return {x_Norm_exp_Zero, "x is Normal, exp is Zero"};
else
return {x_Norm_exp_Norm, "x is Normal, exp is Normal"};
}
post
{
Unifloat* model = ldexp_model(x, exp);
if(isOverflow_Unifloat(model))
{
/*
* If these functions would cause overflow, a range error shall
* occur and ldexp(), ldexpf(), and ldexpl() shall return HUGE_VAL,
* HUGE_VALF, and HUGE_VALL (according to the sign of x),
* respectively.
*/
REQ("ldexp.05;ldexpf.05;ldexpl.05",
"these functions cause overflow",
isInfinity_Unifloat(ldexp_spec));
}
if(isUnderflow_Unifloat(model))
{
if(isRepresentable_Unifloat(model))
{
model = checkRange_Unifloat(model);
/*
* If the correct value would cause underflow, and is
* representable, a range error may occur and the correct value
* shall be returned.
*/
REQ("ldexp.10;ldexpf.10;ldexpl.10",
"the correct value cause underflow and is representable",
compare_Unifloat(ldexp_spec, model) == 0
);
}
else
{
/*
* If the correct value would cause underflow, and is not
* representable, a range error may occur, and [MX] either 0.0
* (if supported), or an implementation-defined value shall be
* returned.
*/
REQ("ldexp.06;ldexpf.06;ldexpl.06",
"the correct value cause underflow and is not representable",
isZero_Unifloat(ldexp_spec)
);
}
}
/*
* These functions shall fail if:
*
* Range Error The result overflows.
*
* These functions may fail if:
*
* Range Error The result underflows.
*/
ERROR_BEGIN(POSIX_LDEXP,
"ldexp.11.01.01;ldexpf.11.01.01;ldexpl.11.01.01;"
"ldexp.12.01.01;ldexpf.12.01.01;ldexpl.12.01.01",
*errno, *errno)
/*
* These functions shall fail if:
*
* Range Error The result overflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is
* non-zero, then errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_LDEXP, ERANGE,
"ldexp.11.01.01;ldexpf.11.01.01;ldexpl.11.01.01",
isOverflow_Unifloat(model))
/*
* These functions may fail if:
*
* Range Error The result underflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is
* non-zero, then errno shall be set to [ERANGE].
*/
ERROR_MAY(POSIX_LDEXP, ERANGE,
"ldexp.12.01.01;ldexpf.12.01.01;ldexpl.12.01.01",
isUnderflow_Unifloat(model))
ERROR_END()
if(isNan_Unifloat(x))
{
#if NAN_SUPPORT == 1
/*
* [MX] If x is NaN, a NaN shall be returned.
*/
REQ("ldexp.07;ldexpf.07;ldexpl.07",
"x is NaN, NaN shall be returned",
isNan_Unifloat(ldexp_spec)
);
#endif
}
if(isZero_Unifloat(x) || isInfinity_Unifloat(x))
{
/*
* If x is 0 or Inf, x shall be returned.
*/
REQ("ldexp.08;ldexpf.08;ldexpl.08",
"x is 0 or Inf, x shall be returned",
compare_Unifloat(x, ldexp_spec) == 0
);
}
if(exp == 0)
{
/*
* If exp is 0, x shall be returned.
*/
REQ("ldexp.09;ldexpf.09;ldexpl.09",
"exp is 0, x shall be returned",
compare_Unifloat(x, ldexp_spec) == 0
);
}
if(isNormal_Unifloat(x))
{
model = checkRange_Unifloat(model);
/*
* Upon successful completion, these functions shall return x
* multiplied by 2, raised to the power exp.
*/
REQ("ldexp.04;ldexpf.04;ldexpl.04",
"shall return x multiplied by 2, raised to the power exp",
compare_Unifloat(ldexp_spec, model) == 0
);
}
return true;
}
FILTER_CLEAN;
}
Unifloat* ldexp_model(Unifloat* x, IntT exp)
{
Unifloat* res = clone(x);
if(!isZero_Unifloat(res));
res->exp += exp;
return res;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
logb, logbf, logbl - radix-independent exponent
SYNOPSIS
#include <math.h>
double logb(double x);
float logbf(float x);
long double logbl(long double x);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. These functions shall compute the exponent of x, which is the
integral part of logr |x|, as a signed floating-point value, for non-zero x,
where r is the radix of the machine's floating-point arithmetic, which is the
value of FLT_RADIX defined in the <float.h> header.
If x is subnormal it is treated as though it were normalized; thus for finite
positive x:
1 <= x * FLT_RADIX-logb(x) < FLT_RADIX
An application wishing to check for error situations should set errno to zero
and call feclearexcept(FE_ALL_EXCEPT) before calling these functions. On
return, if errno is non-zero or fetestexcept (FE_INVALID | FE_DIVBYZERO |
FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred.
RETURN VALUE
Upon successful completion, these functions shall return the exponent of x.
If x is 0, a pole error shall occur and logb(), logbf(), and logbl() shall
return -HUGE_VAL, -HUGE_VALF, and -HUGE_VALL, respectively.
[MX] If x is NaN, a NaN shall be returned.
If x is Inf, +Inf shall be returned.
ERRORS
These functions shall fail if:
Pole Error The value of x is 0.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the divide-by-zero floating-point
exception shall be raised.
*/
//This specification refers to: logbf, logb, logbl
specification
Unifloat* logb_spec(CallContext context, Unifloat* x, ErrorCode* errno)
{
char type[3][50] = {"logbf", "logb", "logbl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
if (isZero_Unifloat(x))
return {Zero_arg, "The argument is zero"};
else
if (isUnderflow_Unifloat(x))
return {Subnormal, "The argument is subnormal"};
else
return {Normal_arg, "The argument is normal"};
}
post
{
Unifloat* model_res = logb_model(x);
if (isZero_Unifloat(x))
{
/*
* If x is 0, a pole error shall occur and logb(), logbf(), and logbl
* shall return -HUGE_VAL, -HUGE_VALF, and -HUGE_VALL, respectively.
*/
REQ("logb.05;logbf.05;logbl.05",
"If x is 0, shall return -HUGE_VAL",
isInfinity_Unifloat(logb_spec) && (logb_spec->sign == -1));
}
/*
* These functions shall fail if:
*
* Pole Error The value of x is 0.
*/
ERROR_BEGIN(POSIX_LOGB,
"logb.08.01.01;logbf.08.01.01;logbl.08.01.01",
*errno, *errno)
/*
* These functions shall fail if:
*
* Pole Error The value of x is 0.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_LOGB, ERANGE,
"logb.08.01.01;logbf.08.01.01;logbl.08.01.01",
isZero_Unifloat(x))
ERROR_END()
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x))
{
/*
* [MX] If x is NaN, a NaN shall be returned.
*/
REQ("logb.06;logbf.06;logbl.06",
"If x is NaN, a NaN shall be returned",
isNan_Unifloat(logb_spec));
}
#endif
if (isInfinity_Unifloat(x))
{
/*
* If x is Inf, +Inf shall be returned.
*/
REQ("logb.07;logbf.07;logbl.07",
"If x is Inf, +Inf shall be returned",
(isInfinity_Unifloat(logb_spec)) && (logb_spec->sign == 1));
}
/*
* Upon successful completion, these functions shall return the
* exponent of x.
*/
REQ("logb.04;logbf.04;logbl.04",
"It shall return the exponent of x",
compare_Unifloat(model_res, logb_spec) == 0);
return true;
}
FILTER_CLEAN;
}
Unifloat* logb_model(Unifloat* x)
{
Unifloat* Inf[3] = {clone(infinity_FloatT), clone(infinity_DoubleT),
clone(infinity_LongDoubleT)};
Unifloat* res = convertInteger_Unifloat(x->exp - 1, x->type);
if (isZero_Unifloat(x))
{
Inf[0]->sign = Inf[1]->sign = Inf[2]->sign = -1;
return Inf[x->type];
}
if (isNan_Unifloat(x)) return clone(x);
if (isInfinity_Unifloat(x)) return Inf[x->type];
return res;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
nextafter, nextafterf, nextafterl, nexttoward, nexttowardf, nexttowardl - next
representable floating-point number
SYNOPSIS
#include <math.h>
double nextafter(double x, double y);
float nextafterf(float x, float y);
long double nextafterl(long double x, long double y);
double nexttoward(double x, long double y);
float nexttowardf(float x, long double y);
long double nexttowardl(long double x, long double y);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the
ISO C standard. Any conflict between the requirements described here and
the ISO C standard is unintentional. This volume of IEEE Std
1003.1-2001 defers to the ISO C standard.
The nextafter(), nextafterf(), and nextafterl() functions shall compute the
next representable floating-point value following x in the direction of y.
Thus, if y is less than x, nextafter() shall return the largest representable
floating-point number less than x. The nextafter(), nextafterf(), and
nextafterl() functions shall return y if x equals y.
The nexttoward(), nexttowardf(), and nexttowardl() functions shall be
equivalent to the corresponding nextafter() functions, except that the second
parameter shall have type long double and the functions shall return y
converted to the type of the function if x equals y.
An application wishing to check for error situations should set errno to zero
and call feclearexcept(FE_ALL_EXCEPT) before calling these functions. On
return, if errno is non-zero or fetestexcept(FE_INVALID | FE_DIVBYZERO |
FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred.
RETURN VALUE
Upon successful completion, these functions shall return the next representable
floating-point value following x in the direction of y.
If x== y, y (of the type x) shall be returned.
If x is finite and the correct function value would overflow, a range error
shall occur and HUGE_VAL, HUGE_VALF, and HUGE_VALL (with the same sign as x)
shall be returned as appropriate for the return type of the function.
[MX] If x or y is NaN, a NaN shall be returned.
If x!= y and the correct function value is subnormal, zero, or underflows, a
range error shall occur, and either the correct function value (if
representable) or 0.0 shall be returned.
ERRORS
These functions shall fail if:
Range Error
The correct value overflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the overflow floating-point exception
shall be raised.
Range Error
[MX] The correct value is subnormal or underflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the underflow floating-point exception
shall be raised.
*/
//This specification refers to: nextafterf, nextafter, nextafterl
specification
Unifloat* nextafter_spec(CallContext context, Unifloat* x, Unifloat* y,
ErrorCode* errno)
{
char type[3][50] = {"nextafterf", "nextafter", "nextafterl"};
FILTER(type[x->type]);
pre
{
/* [Input arguments should be not Null] */
REQ("", "x and y aren't NUll", (x != NULL) && (y != NULL));
/* [Input arguments should have the same type] */
REQ("", "x and y should have the same type", x->type == y->type);
return true;
}
coverage C
{
switch(x->kind)
{
case Infinity:
if (isInfinity_Unifloat(y))
return {Inf_Inf, "x - infinity, y - infinity"};
if (isNan_Unifloat(y))
return {Inf_NaN, "x - infinity, y - NaN"};
if (isNormal_Unifloat(y))
return {Inf_Norm, "x - infinity, y - normal"};
break;
case NaN:
if (isInfinity_Unifloat(y))
return {NaN_Inf, "x - NaN, y - infinity"};
if (isNan_Unifloat(y))
return {NaN_NaN, "x - NaN, y - NaN"};
if (isNormal_Unifloat(y))
return {NaN_Norm, "x - Nan, y - normal"};
break;
case Normal:
if (isInfinity_Unifloat(y))
return {Norm_Inf, "x - normal, y - infinity"};
if (isNan_Unifloat(y))
return {Norm_NaN, "x - normal, y - NaN"};
if (isNormal_Unifloat(y))
{
if (compare_Unifloat(x,y) == 1)
return {Norm_Norm_More, "x - normal, y - normal, x>y"};
if (compare_Unifloat(x,y) == 0)
return {Norm_Norm_Equal, "x - normal, y - normal, x=y"};
if (compare_Unifloat(x,y) == -1)
return {Norm_Norm_Less, "x - normal, y - normal, x<y"};
}
break;
}
}
post
{
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
Unifloat* model_res = nextafter_model(x, y);
round_Unifloat(model_res, mant[x->type]);
round_Unifloat(nextafter_spec, mant[x->type]);
normalize_Unifloat(nextafter_spec);
if (isNormal_Unifloat(x) && isOverflow_Unifloat(model_res))
{
/*
* If x is finite and the correct function value would overflow, a
* range error shall occur and +-HUGE_VAL, +-HUGE_VALF, and
* +-HUGE_VALL (with the same sign as x) shall be returned as
* appropriate for the return type of the function.
*/
REQ("nextafter.07;nextafterf.07;nextafterl.07",
"if overflow occur, function should return +-HUGE_VALF",
isInfinity_Unifloat(nextafter_spec));
}
if ((compare_Unifloat(x,y)!=0) && isUnderflow_Unifloat(model_res))
{
/*
* If x!= y and the correct function value is subnormal, zero, or
underflows, a
* range error shall occur, and either the correct function value (if
* representable) or 0.0 shall be returned.
*/
REQ("nextafter.09;nextafterf.09;nextafterl.09",
"if function is subnormal, then errno=ERANGE, and correct value "
"should be returned ",
!isOverflow_Unifloat(nextafter_spec) );
}
/*
* These functions shall fail if:
* Range Error:
* The correct value overflows.
* The correct value is subnormal or underflows.
*/
ERROR_BEGIN(POSIX_NEXTAFTER, "nextafter.10.01.01;nextafterf.10.01.01;"
"nextafterl.10.01.01;nextafter.10.02.01;nextafterf.10.02.01;"
"nextafterl.10.02.01", *errno, *errno)
/*
* These functions shall fail if:
*
* Range Error
* The correct value overflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non-
zero, then
* errno shall be set to [ERANGE].
*/
/*
* These functions shall fail if:
*
* Range Error
* [MX] The correct value is subnormal or underflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non-
zero, then
* errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_NEXTAFTER, ERANGE, "nextafter.10.01.01;nextafterf.10.01.01;"
"nextafterl.10.01.01;nextafter.10.02.01;nextafterf.10.02.01;"
"nextafterl.10.02.01",
(isOverflow_Unifloat(model_res) && isNormal_Unifloat(x)) /*nextafter.10.01.01*/
|| ((isUnderflow_Unifloat(model_res) || isZero_Unifloat(model_res))
&& (compare_Unifloat(x,y) != 0)) /*nextafter.10.02.01*/
)
ERROR_END()
if (!isOverflow_Unifloat(model_res) && !isUnderflow_Unifloat(model_res))
{
/*
* Upon successful completion, these functions shall return the next
representable
* floating-point value following x in the direction of y.
*/
REQ("nextafter.05;nextafterf.05;nextafterl.05",
"shall return the next representable floating-point value following x",
compare_Unifloat(nextafter_spec, model_res) == 0);
}
if (compare_Unifloat(x,y) == 0)
{
/*
* The nextafter(), nextafterf(), and nextafterl() functions shall return y
* if x equals y.
*/
/*
* If x== y, y (of the type x) shall be returned.
*/
REQ("nextafter.06;nextafterf.06;nextafterl.06;"
"nextafter.02;nextafterf.02;nextafterl.02",
"If x== y, y shall be returned",
compare_Unifloat(nextafter_spec,y) == 0);
}
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x) || isNan_Unifloat(y))
{
/*
* [MX] If x or y is NaN, a NaN shall be returned.
*/
REQ("nextafter.08;nextafterf.08;nextafterl.08",
"If x or y is NaN, a NaN shall be returned",
isNan_Unifloat(nextafter_spec));
}
#endif
return true;
}
FILTER_CLEAN;
}
Unifloat* nextafter_model(Unifloat* x, Unifloat* y)
{
int i;
Unifloat* res;
int leng_num[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
int exponent_max[3] = {maxExp_FloatT, maxExp_DoubleT, maxExp_LongDoubleT};
int exponent_min[3] = {minExp_FloatT-1, minExp_DoubleT-1,
minExp_LongDoubleT-1};
Unifloat* epsilon[3] = {createOne_Unifloat(0),
createOne_Unifloat(1),
createOne_Unifloat(2)};
epsilon[0]->exp = x->exp - digMant_FloatT + 1;
epsilon[1]->exp = x->exp - digMant_DoubleT + 1;
epsilon[2]->exp = x->exp - digMant_LongDoubleT + 1;
for(i = 0; i<3; i++)
if (epsilon[i]->exp < exponent_min[i]-leng_num[i] + 2)
epsilon[i]->exp = exponent_min[i]-leng_num[i] + 2;
if (isNan_Unifloat(y)) return round_Unifloat(clone(y), leng_num[x->type]);
if (isInfinity_Unifloat(x) && isNormal_Unifloat(y))
{
res = createOne_Unifloat(x->type);
res->exp = exponent_max[x->type];
res->sign = x->sign;
for (i=1; i<= x->exp + 1 - epsilon[x->type]->exp; i++)
setMant_Unifloat(res, i, 1);
return res;
}
if (isZero_Unifloat(x) && !isNan_Unifloat(y) && (compare_Unifloat(x,y)!=0))
{
res = createOne_Unifloat(x->type);
res->exp = epsilon[x->type]->exp - x->exp + exponent_min[x->type] + 1;
res->sign = y->sign;
return res;
}
switch(compare_Unifloat(x,y))
{
case 0:
res = clone(y);
//res->prec = leng_num[x->type];
return res;
case 1:
res = sub_Unifloat(x, epsilon[x->type]);
break;
case -1:
res = add_Unifloat(x, epsilon[x->type]);
break;
case 2:
if (isNan_Unifloat(x))
res = sub_Unifloat(x, epsilon[x->type]);
else
res = add_Unifloat(x, epsilon[x->type]);
break;
}
epsilon[x->type]->exp--;
if (res->exp<x->exp)
if (x->sign > 0)
res = add_Unifloat(res, epsilon[x->type]);
else
res = sub_Unifloat(res, epsilon[x->type]);
return res;
}
//This specification refers to: nexttowardf, nexttoward, nexttowardl
specification
Unifloat* nexttoward_spec(CallContext context, Unifloat* x, Unifloat* y,
ErrorCode* errno)
{
char type[3][50] = {"nexttowardf", "nexttoward", "nexttowardl"};
FILTER(type[x->type]);
pre
{
/* [Input arguments should be not Null] */
REQ("", "x and y aren't NUll", (x != NULL) && (y != NULL));
return true;
}
coverage C
{
switch(x->kind)
{
case 0:
if (isInfinity_Unifloat(y))
return {Inf_Inf, "x - infinity, y - infinity"};
if (isNan_Unifloat(y))
return {Inf_NaN, "x - infinity, y - NaN"};
if (isNormal_Unifloat(y))
return {Inf_Norm, "x - infinity, y - normal"};
break;
case 1:
if (isInfinity_Unifloat(y))
return {NaN_Inf, "x - NaN, y - infinity"};
if (isNan_Unifloat(y))
return {NaN_NaN, "x - NaN, y - NaN"};
if (isNormal_Unifloat(y))
return {NaN_Norm, "x - Nan, y - normal"};
break;
case 2:
if (isInfinity_Unifloat(y))
return {Norm_Inf, "x - normal, y - infinity"};
if (isNan_Unifloat(y))
return {Norm_NaN, "x - normal, y - NaN"};
if (isNormal_Unifloat(y))
{
if (compare_Unifloat(x,y) == 1)
return {Norm_Norm_More, "x - normal, y - normal, x>y"};
if (compare_Unifloat(x,y) == 0)
return {Norm_Norm_Equal, "x - normal, y - normal, x=y"};
if (compare_Unifloat(x,y) == -1)
return {Norm_Norm_Less, "x - normal, y - normal, x<y"};
}
break;
}
}
post
{
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
Unifloat* model_res = nextafter_model(x, y);
round_Unifloat(model_res, mant[x->type]);
round_Unifloat(nexttoward_spec, mant[x->type]);
normalize_Unifloat(nexttoward_spec);
if (isNormal_Unifloat(x) && isOverflow_Unifloat(model_res))
{
/*
* If x is finite and the correct function value would overflow, a
* range error shall occur and +-HUGE_VAL, +-HUGE_VALF, and
* +-HUGE_VALL (with the same sign as x) shall be returned as
* appropriate for the return type of the function.
*/
REQ("nexttoward.06;nexttowardf.06;nexttowardl.06",
"if overflow occur, function should return +-HUGE_VALF and errno="
"ERANGE",
isInfinity_Unifloat(nexttoward_spec));
}
if ((compare_Unifloat(x,y)!=0) && isUnderflow_Unifloat(model_res))
{
/*
* If x!= y and the correct function value is subnormal, zero, or
underflows, a
* range error shall occur, and either the correct function value (if
* representable) or 0.0 shall be returned.
*/
REQ("nexttoward.08;nexttowardf.08;nexttowardl.08",
"if function is subnormal, then errno=ERANGE, and correct value "
"should be returned ",
!isOverflow_Unifloat(nexttoward_spec));
}
/*
* These functions shall fail if:
*
* Range Error:
* The correct value overflows.
* The correct value is subnormal or underflows.
*/
ERROR_BEGIN(POSIX_NEXTTOWARD,
"nexttoward.09.01.01;nexttowardf.09.01.01;nexttowardl.09.01.01;"
"nexttoward.09.02.01;nexttowardf.09.02.01;nexttowardl.09.02.01;",
*errno, *errno)
/*
* These functions shall fail if:
*
* Range Error
* The correct value overflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non-
zero, then
* errno shall be set to [ERANGE].
*/
/*
* These functions shall fail if:
*
* Range Error
* [MX] The correct value is subnormal or underflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non-
zero, then
* errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_NEXTTOWARD, ERANGE, "nexttoward.09.01.01;"
"nexttowardf.09.01.01;nexttowardl.09.01.01;nexttoward.09.02.01;"
"nexttowardf.09.02.01;nexttowardl.09.02.01;",
(isOverflow_Unifloat(model_res) && isNormal_Unifloat(x)) /*nexttoward.09.01.01*/
|| ((isUnderflow_Unifloat(model_res) || isZero_Unifloat(model_res))
&& (compare_Unifloat(x,y) != 0)) /*nexttoward.09.02.01*/)
ERROR_END()
if (!isOverflow_Unifloat(model_res)&&!isUnderflow_Unifloat(model_res))
{
/*
* Upon successful completion, these functions shall return the next
representable
* floating-point value following x in the direction of y.
*/
REQ("nexttoward.04;nexttowardf.04;nexttowardl.04",
"shall return the next representable floating-point value following x",
compare_Unifloat(nexttoward_spec, checkRange_Unifloat(model_res)) == 0);
}
if (compare_Unifloat(x,y) == 0)
{
/*
* If x== y, y (of the type x) shall be returned.
*/
REQ("nexttoward.05;nexttowardf.05;nexttowardl.05",
"If x== y, y shall be returned",
compare_Unifloat(nexttoward_spec,y) == 0);
}
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x) || isNan_Unifloat(y))
{
/*
* [MX] If x or y is NaN, a NaN shall be returned.
*/
REQ("nexttoward.07;nexttowardf.07;nexttowardl.07",
"If x or y is NaN, a NaN shall be returned",
isNan_Unifloat(nexttoward_spec));
}
#endif
return true;
}
FILTER_CLEAN;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
scalb - load exponent of a radix-independent floating-point number
SYNOPSIS
[OB XSI] #include <math.h>
double scalb(double x, double n);
DESCRIPTION
The scalb() function shall compute x*rn, where r is the radix of the machine's
floating-point arithmetic. When r is 2, scalb() shall be equivalent to ldexp().
The value of r is FLT_RADIX which is defined in <float.h>.
An application wishing to check for error situations should set errno to zero
and call feclearexcept(FE_ALL_EXCEPT) before calling these functions. On
return, if errno is non-zero or fetestexcept(FE_INVALID | FE_DIVBYZERO |
FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred.
RETURN VALUE
Upon successful completion, the scalb() function shall return x*rn.
If x or n is NaN, a NaN shall be returned.
If n is zero, x shall be returned.
If x is Inf and n is not -Inf, x shall be returned.
If x is 0 and n is not +Inf, x shall be returned.
If x is 0 and n is +Inf, a domain error shall occur, and either a NaN (if
supported), or an implementation-defined value shall be returned.
If x is Inf and n is -Inf, a domain error shall occur, and either a NaN (if
supported), or an implementation-defined value shall be returned.
If the result would cause an overflow, a range error shall occur and HUGE_VAL
(according to the sign of x) shall be returned.
If the correct value would cause underflow, and is representable, a range error
may occur and the correct value shall be returned.
If the correct value would cause underflow, and is not representable, a range
error may occur, and 0.0 shall be returned.
ERRORS
The scalb() function shall fail if:
Domain Error If x is zero and n is +Inf, or x is Inf and n is -Inf.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [EDOM]. If the integer expression (math_errhandling &
MATH_ERREXCEPT) is non-zero, then the invalid floating-point exception shall be
raised.
Range Error The result would overflow.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the overflow floating-point exception
shall be raised.
The scalb() function may fail if:
Range Error The result underflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the underflow floating-point exception
shall be raised.
*/
//This specification refers to: scalbf, scalb, scalbl
specification
Unifloat* scalb_spec(CallContext context, Unifloat* x, Unifloat* n,
ErrorCode* errno)
{
char type[3][50] = {"scalbf", "scalb", "scalbl"};
FILTER(type[x->type]);
pre
{
/* [Input arguments should be not Null] */
REQ("", "x and n aren't Null", (x != NULL) && (n != NULL));
return true;
}
coverage C
{
if (isNan_Unifloat(x) || isNan_Unifloat(n))
return {Nan_Nan, "x or n is NaN"};
if (isZero_Unifloat(n))
return {Zero_n, "n is zero"};
if (isInfinity_Unifloat(x))
if (isInfinity_Unifloat(n))
return {Inf_Inf, "x and n are infinity"};
else
return {Inf_Norm, "x - infinite value, n - finite value"};
if (isZero_Unifloat(x))
if (isInfinity_Unifloat(n))
return {Null_Inf, "x is zero, n is infinity"};
else
return {Null_Norm, "x is zero, n - finite value"};
else
if (isInfinity_Unifloat(n))
return {Norm_Inf, "x is non-zero, n is infinity"};
else
return {Norm_Norm, "x is non-zero, n - finite value"};
}
post
{
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
/*[Calculate model function]*/
Unifloat* model_res = scalb_model(x, n);
/* [nextafter_spec has PRECISION numbers in mantissa. It should be
* decreased to mantissa in appropriate type]*/
round_Unifloat(scalb_spec, mant[x->type]);
#if NAN_SUPPORT == 1
if (isZero_Unifloat(x) && isInfinity_Unifloat(n) && (n->sign == 1))
{
/*
* If x is 0 and n is +Inf, a domain error shall occur, and either
* a NaN (if supported), or an implementation-defined value shall
* be returned.
*/
REQ("scalb.09;scalbf.09;scalbl.09",
"If x is 0 and n is +Inf, a NaN shall be returned",
isNan_Unifloat(scalb_spec));
}
if (isInfinity_Unifloat(x) && isInfinity_Unifloat(n) && (n->sign == -1))
{
/*
* If x is Inf and n is -Inf, a domain error shall occur, and
* either a NaN (if supported), or an implementation-defined value
* shall be returned.
*/
REQ("scalb.10;scalbf.10;scalbl.10",
"If x is Inf and n is -Inf, a NaN shall be returned",
isNan_Unifloat(scalb_spec));
}
#endif
if (isOverflow_Unifloat(model_res))
{
/*
* If the result would cause an overflow, a range error shall occur
* and HUGE_VAL (according to the sign of x) shall be returned.
*/
REQ("scalb.11;scalbf.11;scalbl.11",
"If the result would cause an overflow,"
" HUGE_VAL shall be returned.",
isInfinity_Unifloat(scalb_spec));
}
if (isUnderflow_Unifloat(model_res) && isRepresentable_Unifloat(model_res))
{
/*
* If the correct value would cause underflow, and is
* representable, a range error may occur and the correct value
* shall be returned.
*/
REQ("scalb.12;scalbf.12;scalbl.12",
"If the correct value would cause underflow, and is "
"representable, the correct value shall be returned",
compare_Unifloat(model_res, scalb_spec) == 0);
}
if (isUnderflow_Unifloat(model_res) && !isRepresentable_Unifloat(model_res))
{
/*
* If the correct value would cause underflow, and is not
* representable, a range error may occur, and 0.0 shall be
* returned.
*/
REQ("scalb.13;scalbf.13;scalbl.13",
"If the correct value would cause underflow, and is not "
"representable, 0.0 shall be returned",
isZero_Unifloat(scalb_spec));
}
/*
* The scalb() function shall fail if:
*
* Domain Error: If x is zero and n is +Inf, or x is Inf and n is -Inf
* Range Error: The result would overflow.
*
* The scalb() function may fail if:
*
* Range Error The result underflows.
*/
ERROR_BEGIN(POSIX_SCALB,
"scalb.14.01.01;scalbf.14.01.01;scalbl.14.01.01;"
"scalb.14.02.01;scalbf.14.02.01;scalbl.14.02.01;"
"scalb.15.01.01;scalbf.15.01.01;scalbl.15.01.01;",
*errno, *errno)
/*
* The scalb() function shall fail if:
*
* Domain Error If x is zero and n is +Inf, or x is Inf and n is -
* Inf. If the integer expression (math_errhandling & MATH_ERRNO)
* is non-zero, then errno shall be set to [EDOM].
*/
ERROR_SHALL(POSIX_SCALB, EDOM,
"scalb.14.01.01;scalbf.14.01.01;scalbl.14.01.01",
isZero_Unifloat(x) && isInfinity_Unifloat(n) &&
(n->sign == 1) ||
isInfinity_Unifloat(x) && isInfinity_Unifloat(n) &&
(n->sign == -1))
/*
* The scalb() function shall fail if:
*
* Range Error The result would overflow.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_SCALB, ERANGE,
"scalb.14.02.01;scalbf.14.02.01;scalbl.14.02.01",
isOverflow_Unifloat(model_res) )
/*
* The scalb() function may fail if:
*
* If the integer expression (math_errhandling & MATH_ERREXCEPT)
* is non-zero, then the underflow floating-point exception shall
* be raised.
*/
/*
* The scalb() function may fail if:
*
* Range Error The result underflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_MAY(POSIX_SCALB, ERANGE,
"scalb.15.01.01;scalbf.15.01.01;scalbl.15.01.01",
isUnderflow_Unifloat(model_res))
ERROR_END()
if (!isOverflow_Unifloat(model_res) && !isUnderflow_Unifloat(model_res))
{
/*
* Upon successful completion, the scalb() function shall return
* x*rn.
*/
REQ("scalb.04;scalbf.04;scalbl.04",
"It shall return x*rn",
compare_Unifloat(model_res, scalb_spec) == 0);
}
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x) || isNan_Unifloat(n))
{
/*
* If x or n is NaN, a NaN shall be returned.
*/
REQ("scalb.05;scalbf.05;scalbl.05",
"If x or n is NaN, a NaN shall be returned",
isNan_Unifloat(scalb_spec));
}
#endif
if (isZero_Unifloat(n))
{
/*
* If n is zero, x shall be returned.
*/
REQ("scalb.06;scalbf.06;scalbl.06",
"If n is zero, x shall be returned",
compare_Unifloat(x, scalb_spec) == 0);
}
if (isInfinity_Unifloat(x) &&
!(isInfinity_Unifloat(n) && (n->sign == -1)))
{
/*
* If x is Inf and n is not -Inf, x shall be returned.
*/
REQ("scalb.07;scalbf.07;scalbl.07",
"If x is Inf and n is not -Inf, x shall be returned",
compare_Unifloat(x, scalb_spec) == 0);
}
if (isZero_Unifloat(x) && !(isInfinity_Unifloat(n) && (n->sign == 1)))
{
/*
* If x is 0 and n is not +Inf, x shall be returned.
*/
REQ("scalb.08;scalbf.08;scalbl.08",
"If x is 0 and n is not +Inf, x shall be returned",
compare_Unifloat(x, scalb_spec) == 0);
}
return true;
}
FILTER_CLEAN;
}
Unifloat* scalb_model(Unifloat* x, Unifloat* n)
{
Unifloat* Nan[3] = {clone(nan_FloatT), clone(nan_DoubleT),
clone(nan_LongDoubleT)};
Unifloat* res = clone(x);
IntT error;
IntT exp = convertUnifloat_Integer(n, &error);
if (isNan_Unifloat(x) || isNan_Unifloat(n))
return Nan[x->type];
if (isZero_Unifloat(n))
return clone(x);
if (isNormal_Unifloat(x) && !isZero_Unifloat(x)
&& (isInfinity_Unifloat(n)) && (n->sign == 1))
return clone(n);
if (isNormal_Unifloat(x) && (isInfinity_Unifloat(n)) && (n->sign == -1))
{
Unifloat* Zero = createZero_Unifloat(x->type);
Zero->sign = x->sign;
return Zero;
}
if (isInfinity_Unifloat(x) && !(isInfinity_Unifloat(n) && (n->sign == -1)))
return clone(x);
if (isInfinity_Unifloat(x) && isInfinity_Unifloat(n) && (n->sign == -1))
return Nan[x->type];
if (isZero_Unifloat(x) && !(isInfinity_Unifloat(n) && (n->sign == 1)))
return clone(x);
if (isZero_Unifloat(x) && isInfinity_Unifloat(n) && (n->sign == 1))
return Nan[x->type];
if ((error == 2) || (error == 3))
return Nan[x->type];
res->exp += exp;
return res;
}
/*
Linux Standard Base Core Specification 3.1
Copyright (c) 2004, 2005 Free Standards Group
refers
The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition
Copyright (c) 2001-2004 The IEEE and The Open Group, All Rights reserved.
-------------------------------------------------------------------------------
NAME
scalbln, scalblnf, scalblnl, scalbn, scalbnf, scalbnl - compute exponent using
FLT_RADIX
SYNOPSIS
#include <math.h>
double scalbln(double x, long n);
float scalblnf(float x, long n);
long double scalblnl(long double x, long n);
double scalbn(double x, int n);
float scalbnf(float x, int n);
long double scalbnl(long double x, int n);
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO
C standard. Any conflict between the requirements described here and the ISO C
standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the
ISO C standard. These functions shall compute x * FLT_RADIX n efficiently, not
normally by computing FLT_RADIXn explicitly.
An application wishing to check for error situations should set errno to zero
and call feclearexcept(FE_ALL_EXCEPT) before calling these functions. On
return, if errno is non-zero or fetestexcept(FE_INVALID | FE_DIVBYZERO |
FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred.
RETURN VALUE
Upon successful completion, these functions shall return x * FLT_RADIX n.
If the result would cause overflow, a range error shall occur and these
functions shall return HUGE_VAL, HUGE_VALF, and HUGE_VALL (according to the
sign of x) as appropriate for the return type of the function.
If the correct value would cause underflow, and is not representable, a range
error may occur, and [MX] either 0.0 (if supported), or an implementation-
defined value shall be returned.
[MX] If x is NaN, a NaN shall be returned.
If x is 0 or Inf, x shall be returned.
If n is 0, x shall be returned.
If the correct value would cause underflow, and is representable, a range error
may occur and the correct value shall be returned.
ERRORS
These functions shall fail if:
Range Error The result overflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the overflow floating-point exception
shall be raised.
These functions may fail if:
Range Error The result underflows.
If the integer expression (math_errhandling & MATH_ERRNO) is non-zero, then
errno shall be set to [ERANGE]. If the integer expression (math_errhandling &
amp; MATH_ERREXCEPT) is non-zero, then the underflow floating-point exception
shall be raised.
*/
//This specification refers to: scalblnf, scalbln, scalblnl
specification
Unifloat* scalbln_spec(CallContext context, Unifloat* x, LongT n,
ErrorCode* errno)
{
char type[3][50] = {"scalblnf", "scalbln", "scalblnl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isNan_Unifloat(x))
return {NaN_arg, "x - NaN"};
else
if (isInfinity_Unifloat(x))
return {Inf_arg, "x - Infinity"};
else
if (isZero_Unifloat(x))
return {Zero_arg, "x - zero"};
else
if (n == 0)
return {zero_n, "x - finite non-zero value, n - zero"};
else
return {normal_arg,
"x - finite non-zero value, n - non-zero"};
}
post
{
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
/*[Calculate model function]*/
Unifloat* model_res = scalbln_model(x, n);
/* [nextafter_spec has PRECISION numbers in mantissa. It should be
* decreased to mantissa in appropriate type]*/
round_Unifloat(scalbln_spec, mant[x->type]);
if (isOverflow_Unifloat(model_res))
{
/*
* If the result would cause overflow, a range error shall occur
* and these functions shall return HUGE_VAL, HUGE_VALF, and
* HUGE_VALL (according to the sign of x) as appropriate for the
* return type of the function.
*/
REQ("scalbln.05;scalblnf.05;scalblnl.05",
"If the result would cause overflow, it shall return HUGE_VAL",
isInfinity_Unifloat(scalbln_spec));
}
if (isUnderflow_Unifloat(model_res) && !isRepresentable_Unifloat(model_res))
{
/*
* If the correct value would cause underflow, and is not
* representable, a range error may occur, and [MX] either 0.0
* (if supported), or an implementation-defined value shall
* be returned.
*/
REQ("scalbln.06;scalblnf.06;scalblnl.06",
"If the correct value would cause underflow, and is not"
" representable, 0.0 shall be returned",
isZero_Unifloat(scalbln_spec));
}
if (isUnderflow_Unifloat(model_res) && isRepresentable_Unifloat(model_res))
{
/*
* If the correct value would cause underflow, and is
* representable, a range error may occur and the correct value
* shall be returned.
*/
REQ("scalbln.10;scalblnf.10;scalblnl.10",
"If the correct value would cause underflow, and is "
" representable, the correct value shall be returned",
compare_Unifloat(model_res, scalbln_spec) == 0);
}
/*
* These functions shall fail if:
*
* Range Error The result overflows.
*
* These functions may fail if:
*
* Range Error The result underflows.
*/
ERROR_BEGIN(POSIX_SCALBLN,
"scalbln.11.01.01;scalblnf.11.01.01;scalblnl.11.01.01;"
"scalbln.12.01.01;scalblnf.12.01.01;scalblnl.12.01.01",
*errno, *errno)
/*
* These functions shall fail if:
*
* Range Error The result overflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_SCALBLN, ERANGE,
"scalbln.11.01.01;scalblnf.11.01.01;scalblnl.11.01.01",
isOverflow_Unifloat(model_res))
/*
* These functions may fail if:
*
* Range Error The result underflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_MAY(POSIX_SCALBLN, ERANGE,
"scalbln.12.01.01;scalblnf.12.01.01;scalblnl.12.01.01",
isUnderflow_Unifloat(model_res))
ERROR_END()
if (!isOverflow_Unifloat(model_res) &&
!isUnderflow_Unifloat(model_res))
{
/*
* Upon successful completion, these functions shall return
* x * FLT_RADIX n.
*/
REQ("scalbln.04;scalblnf.04;scalblnl.04",
"It shall return x * FLT_RADIX n",
compare_Unifloat(model_res, scalbln_spec) == 0);
}
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x))
{
/*
* [MX] If x is NaN, a NaN shall be returned.
*/
REQ("scalbln.07;scalblnf.07;scalblnl.07",
"If x is NaN, a NaN shall be returned",
isNan_Unifloat(scalbln_spec));
}
#endif
if (isZero_Unifloat(x) || isInfinity_Unifloat(x))
{
/*
* If x is 0 or Inf, x shall be returned.
*/
REQ("scalbln.08;scalblnf.08;scalblnl.08",
"If x is 0 or Inf, x shall be returned",
compare_Unifloat(x, scalbln_spec) == 0);
}
if (n == 0)
{
/*
* If n is 0, x shall be returned.
*/
REQ("scalbln.09;scalblnf.09;scalblnl.09",
"If n is 0, x shall be returned",
compare_Unifloat(x, scalbln_spec) == 0);
}
return true;
}
FILTER_CLEAN;
}
Unifloat* scalbln_model(Unifloat* x, LongT n)
{
Unifloat* res;
if (isNan_Unifloat(x) || isInfinity_Unifloat(x) || isZero_Unifloat(x) ||
(n == 0))
return clone(x);
res = clone(x);
if ((n > SUT_INT_MAX - res->exp) && (res->exp > 0) ||
(n - res->exp > SUT_INT_MAX) && (res->exp < 0))
res->exp = SUT_INT_MAX;
else
if ((n <SUT_INT_MIN - res->exp) && (res->exp <0) ||
(n + res->exp < SUT_INT_MIN) && (res->exp > 0))
res->exp = SUT_INT_MIN;
else
res->exp += n;
return res;
}
//This specification refers to: scalbnf, scalbn, scalbnl
specification
Unifloat* scalbn_spec(CallContext context, Unifloat* x, IntT n,
ErrorCode* errno)
{
char type[3][50] = {"scalbnf", "scalbn", "scalbnl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isNan_Unifloat(x))
return {NaN_arg, "x - NaN"};
else
if (isInfinity_Unifloat(x))
return {Inf_arg, "x - Infinity"};
else
if (isZero_Unifloat(x))
return {Zero_arg, "x - zero"};
else
if (n == 0)
return {zero_n, "x - finite non-zero value, n - zero"};
else
return {normal_arg,
"x - finite non-zero value, n - non-zero"};
}
post
{
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
/*[Calculate model function]*/
Unifloat* model_res = scalbln_model(x, n);
/* [nextafter_spec has PRECISION numbers in mantissa. It should be
* decreased to mantissa in appropriate type]*/
round_Unifloat(scalbn_spec, mant[x->type]);
if (isOverflow_Unifloat(model_res))
{
/*
* If the result would cause overflow, a range error shall occur
* and these functions shall return HUGE_VAL, HUGE_VALF, and
* HUGE_VALL (according to the sign of x) as appropriate for the
* return type of the function.
*/
REQ("scalbn.05;scalbnf.05;scalbnl.05",
"If the result would cause overflow, it shall return HUGE_VAL",
isInfinity_Unifloat(scalbn_spec));
}
if (isUnderflow_Unifloat(model_res)
&& !isRepresentable_Unifloat(model_res))
{
/*
* If the correct value would cause underflow, and is not
* representable, a range error may occur, and [MX] either 0.0
* (if supported), or an implementation-defined value shall
* be returned.
*/
REQ("scalbn.06;scalbnf.06;scalbnl.06",
"If the correct value would cause underflow, and is not"
" representable, 0.0 shall be returned",
isZero_Unifloat(scalbn_spec));
}
if (isUnderflow_Unifloat(model_res) &&
isRepresentable_Unifloat(model_res))
{
/*
* If the correct value would cause underflow, and is
* representable, a range error may occur and the correct value
* shall be returned.
*/
REQ("scalbn.10;scalbnf.10;scalbnl.10",
"If the correct value would cause underflow, and is "
" representable, the correct value shall be returned",
compare_Unifloat(model_res, scalbn_spec) == 0);
}
ERROR_BEGIN(POSIX_SCALBN,
"scalbn.11.01.01;scalbnf.11.01.01;scalbnl.11.01.01;"
"scalbn.12.01.01;scalbnf.12.01.01;scalbnl.12.01.01",
*errno, *errno)
/*
* These functions shall fail if:
*
* Range Error The result overflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_SHALL(POSIX_SCALBN, ERANGE,
"scalbn.11.01.01;scalbnf.11.01.01;scalbnl.11.01.01",
isOverflow_Unifloat(model_res))
/*
* These functions may fail if:
*
* Range Error The result underflows.
*
* If the integer expression (math_errhandling & MATH_ERRNO) is non
* -zero, then errno shall be set to [ERANGE].
*/
ERROR_MAY(POSIX_SCALBN, ERANGE,
"scalbn.12.01.01;scalbnf.12.01.01;scalbnl.12.01.01",
isUnderflow_Unifloat(model_res))
/*
* These functions may fail if:
*
* Range Error The result underflows.
*
* If the integer expression (math_errhandling & MATH_ERREXCEPT)
* is non-zero, then the underflow floating-point exception shall
* be raised.
*/
ERROR_END()
if (!isOverflow_Unifloat(model_res) && !isUnderflow_Unifloat(model_res))
{
/*
* Upon successful completion, these functions shall return
* x * FLT_RADIX n.
*/
REQ("scalbn.04;scalbnf.04;scalbnl.04",
"It shall return x * FLT_RADIX n",
compare_Unifloat(model_res, scalbn_spec) == 0);
}
#if NAN_SUPPORT == 1
if (isNan_Unifloat(x))
{
/*
* [MX] If x is NaN, a NaN shall be returned.
*/
REQ("scalbn.07;scalbnf.07;scalbnl.07",
"If x is NaN, a NaN shall be returned",
isNan_Unifloat(scalbn_spec));
}
#endif
if (isZero_Unifloat(x) || isInfinity_Unifloat(x))
{
/*
* If x is 0 or Inf, x shall be returned.
*/
REQ("scalbn.08;scalbnf.08;scalbnl.08",
"If x is 0 or Inf, x shall be returned",
compare_Unifloat(x, scalbn_spec) == 0);
}
if (n == 0)
{
/*
* If n is 0, x shall be returned.
*/
REQ("scalbn.09;scalbnf.09;scalbnl.09",
"If n is 0, x shall be returned",
compare_Unifloat(x, scalbn_spec) == 0);
}
return true;
}
FILTER_CLEAN;
}
/*
NAME
significand, significandf, significandl -- get mantissa of floating point number
SYNOPSIS
#include <math.h>
double significand(double x);
float significandf(float x);
long double significandf(long double x);
DESCRIPTION
The significand(), significandf(), significandl() functions return the
mantissa of x scaled to the range [1,2).
The significand(), significandf(), significandl() functions are equivalent
to the corresponding scalb(x, (double) -ilogb(x)), scalbf(x, (float) -ilogbf(x)),
scalbl(x, (long double) -ilogbl(x)).
The significandf() function is a single-precision version of significand().
The significandl() function is a double-precision version of significand().
RETURN VALUE
Functions shall return sig, where x := sig* 2**n with 1 <= sig < 2.
if x is 0, 0 shall be returned.
if x is Inf, Inf shall be returned.
If x is NaN, a NaN shall be returned.
ERRORS
No errors are defined.
*/
//This specification refers to: significandf, significand, significandl
specification
Unifloat* significand_spec(CallContext context, Unifloat* x)
{
char type[3][50] = {"significandf", "significand", "significandl"};
FILTER(type[x->type]);
pre
{
/* [Input argument should be not Null] */
REQ("", "x isn't NUll", x != NULL);
return true;
}
coverage C
{
if (isInfinity_Unifloat(x))
return { Infinity_arg, "The argument is infinity" };
else
if (isNan_Unifloat(x))
return {Nan_arg, "The argument is NaN"};
else
if (isZero_Unifloat(x))
return {Zero_arg, "The argument is zero"};
else
if (isUnderflow_Unifloat(x))
return {Subnormal, "The argument is subnormal"};
else
return {Normal_arg, "The argument is normal"};
}
post
{
Unifloat* One = createOne_Unifloat(x->type);
Unifloat* Two = convertInteger_Unifloat(2, x->type);
int mant[3] = {digMant_FloatT, digMant_DoubleT, digMant_LongDoubleT};
Unifloat* model_res = significand_model(x);
Unifloat* model_scalb = scalb_model(x,
mul_Unifloat(convertInteger_Unifloat(ilogb_model(x), x->type),
convertInteger_Unifloat(-1, x->type)));
round_Unifloat(significand_spec, mant[x->type]);
/*
* The significand(), significandf(), significandl() functions are equivalent to
* the corresponding scalb(x, (double) -ilogb(x)), scalbf(x, (float) -ilogbf(x)),
* scalbl(x, (long double) -ilogbl(x)).
*/
REQ("significand.02;significandf.02;significandl.02",
"Functions are equivalent to the corresponding scalb(x, (double) -ilogb(x))",
compare_Unifloat(model_scalb, significand_spec) == 0);
/*
* Functions shall return sig, where x := sig* 2**n
*/
REQ("significand.03;significandf.04;significandl.04",
"Functions shall return sig, where x := sig* 2**n",
compare_Unifloat(model_res, significand_spec) == 0);
if (isNormal_Unifloat(x) && !isZero_Unifloat(x))
{
/*
* with 1 <= |sig| < 2.
*/
REQ("significand.04;significandf.05;significandl.05",
"It return the mantissa scaled to the range [1,2)",
(compare_Unifloat(abs_Unifloat(significand_spec), One) != -1) &&
(compare_Unifloat(abs_Unifloat(significand_spec), Two) == -1));
}
if (isZero_Unifloat(x))
{
/*
* if x is 0, 0 shall be returned.
*/
REQ("significand.05;significandf.06;significandl.06",
"if x is 0, 0 shall be returned",
isZero_Unifloat(significand_spec) && (x->sign == significand_spec->sign));
}
if (isInfinity_Unifloat(x))
{
/*
* if x is Inf, Inf shall be returned.
*/
REQ("significand.06;significandf.07;significandl.07",
"if x is Inf, Inf shall be returned",
isInfinity_Unifloat(significand_spec) && (x->sign == significand_spec->sign));
}
#if NAN_SUPPORT
if (isNan_Unifloat(x))
{
/*
* If x is NaN, a NaN shall be returned.
*/
REQ("significand.07;significandf.08;significandl.08",
"If x is NaN, a NaN shall be returned",
isNan_Unifloat(significand_spec));
}
#endif
return true;
}
FILTER_CLEAN;
}
Unifloat* significand_model(Unifloat* x)
{
Unifloat* res = clone(x);
res->exp = 1;
return res;
}
/********************************************************************/
/** Helper Functions **/
/********************************************************************/