reactos/sdk/lib/crt/math/arm/__fto64_worker.h
2021-07-30 14:20:23 +03:00

103 lines
2.1 KiB
C

/*
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Implementation of __dtoi64
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
*/
#ifdef _USE_64_BITS_
typedef double FLOAT_TYPE;
typedef unsigned long long FINT_TYPE;
#define FRACTION_LEN 52
#define EXPONENT_LEN 11
#else
typedef float FLOAT_TYPE;
typedef unsigned int FINT_TYPE;
#define FRACTION_LEN 23
#define EXPONENT_LEN 8
#endif
typedef
#ifndef _USE_SIGNED_
unsigned
#endif
long long FTO64_RESULT;
#define SIGN_MASK (((FINT_TYPE)1) << (FRACTION_LEN + EXPONENT_LEN))
#define FRACTION_ONE (((FINT_TYPE)1) << FRACTION_LEN)
#define FRACTION_MASK ((FRACTION_ONE) - 1)
#define EXPONENT_MASK ((1 << EXPONENT_LEN) - 1)
#define EXPONENT_ZERO ((1 << (EXPONENT_LEN - 1)) - 1)
#ifdef _USE_SIGNED_
#define EXPONENT_MAX 62
#define INTNAN 0x8000000000000000ULL
#else
#define EXPONENT_MAX 63
#define INTNAN 0xFFFFFFFFFFFFFFFFULL
#endif
#define EXPONENT_INFINITY EXPONENT_MASK
#define NEGATE(x) (~(x) + 1)
FTO64_RESULT
__fto64_worker(FLOAT_TYPE value)
{
union {
FLOAT_TYPE val_float;
FINT_TYPE val_int;
} u;
int exponent;
FTO64_RESULT fraction;
u.val_float = value;
exponent = (int)(u.val_int >> FRACTION_LEN);
exponent &= EXPONENT_MASK;
/* infinity and other NaNs */
if (exponent == EXPONENT_INFINITY)
return INTNAN;
/* subnormals and signed zeros */
if (exponent == 0)
return 0;
exponent -= EXPONENT_ZERO;
/* number is less then one */
if (exponent < 0)
return 0;
/* number is too big */
if (exponent > EXPONENT_MAX)
return INTNAN;
#ifndef _USE_SIGNED_
if (u.val_int & SIGN_MASK)
return INTNAN;
#endif
fraction = u.val_int & FRACTION_MASK;
fraction |= FRACTION_ONE;
exponent -= FRACTION_LEN;
if (exponent != 0)
{
if (exponent < 0)
fraction = fraction >> NEGATE(exponent);
else
fraction = fraction << exponent;
}
#ifdef _USE_SIGNED_
if (u.val_int & SIGN_MASK)
fraction = NEGATE(fraction);
#endif
return fraction;
}