#define PROPS_FLOAT_BITS 32
#define PROPS_FLOAT_DIGITS 24
#define PROPS_FLOAT_DIGITS10 6
#define PROPS_FLOAT_SIGNBIT_BITS 1
#define PROPS_FLOAT_SIGNBIT_MASK (1 << (PROPS_FLOAT_BITS-1))
#define PROPS_FLOAT_MANTISSA_BITS (PROPS_FLOAT_DIGITS - 1)
#define PROPS_FLOAT_MANTISSA_MASK ((1 << PROPS_FLOAT_MANTISSA_BITS) - 1)
#define PROPS_FLOAT_EXPONENT_BITS (PROPS_FLOAT_BITS - PROPS_FLOAT_MANTISSA_BITS - PROPS_FLOAT_SIGNBIT_BITS)
#define PROPS_FLOAT_MIN_EXPONENT (-125)
#define PROPS_FLOAT_MAX_EXPONENT (128)
#define PROPS_FLOAT_INFINITY (HUGE_VALF)
#define PROPS_FLOAT_EXPONENT_OFFSET (2 - PROPS_FLOAT_MIN_EXPONENT)
#define PROPS_FLOAT_EXPONENT_MASK (((1 << PROPS_FLOAT_EXPONENT_BITS) - 1) << PROPS_FLOAT_MANTISSA_BITS)

#define PROPS_DOUBLE_BITS 64
#define PROPS_DOUBLE_DIGITS 53
#define PROPS_DOUBLE_DIGITS10 15
#define PROPS_DOUBLE_SIGNBIT_BITS 1
#define PROPS_DOUBLE_SIGNBIT_MASK (1 << (PROPS_DOUBLE_BITS-1))
#define PROPS_DOUBLE_MANTISSA_BITS (PROPS_DOUBLE_DIGITS - 1)
#define PROPS_DOUBLE_MANTISSA_MASK ((1 << PROPS_DOUBLE_MANTISSA_BITS) - 1)
#define PROPS_DOUBLE_EXPONENT_BITS (PROPS_DOUBLE_BITS - PROPS_DOUBLE_MANTISSA_BITS - PROPS_DOUBLE_SIGNBIT_BITS)
#define PROPS_DOUBLE_MIN_EXPONENT (-1021)
#define PROPS_DOUBLE_MAX_EXPONENT (1024)
#define PROPS_DOUBLE_INFINITY (HUGE_VAL)
#define PROPS_DOUBLE_EXPONENT_OFFSET (2 - PROPS_DOUBLE_MIN_EXPONENT)
#define PROPS_DOUBLE_EXPONENT_MASK (((1 << PROPS_DOUBLE_EXPONENT_BITS) - 1) << PROPS_DOUBLE_MANTISSA_BITS)

#define LSR_D(x) (int)(((unsigned long)(as_long(x) & (long)PROPS_DOUBLE_EXPONENT_MASK)) >> PROPS_DOUBLE_MANTISSA_BITS)
#define LSR_F(x) (int)(((unsigned)(as_int(x) & (int)PROPS_FLOAT_EXPONENT_MASK)) >> PROPS_FLOAT_MANTISSA_BITS)

#define MULSIGN(FTYPE, ITYPE, SIGNMASK)                                     \
    FTYPE _CL_OVERLOADABLE inline mulsign(FTYPE x, FTYPE y)          \
    {                                                                       \
      ITYPE value = as_ ## ITYPE(x);                                        \
      ITYPE sign = as_ ## ITYPE(y) & SIGNMASK;                              \
      return as_ ## FTYPE(value ^ sign);                                    \
    }
