Исходные коды спецификаций для LSB Core 3.1

/*
 * 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                         **/
/********************************************************************/