Я играю с реализацией NaN tagging в небольшой реализации языка я пишу в C. Для этого мне нужно взять двойные и ткнуть прямо на своих битах.Как работать с удвоениями на уровне бит в стандартном C89?
У меня он работает в настоящее время с помощью литья накидного:
typedef union
{
double num;
unsigned long bits;
} Value;
/* A mask that selects the sign bit. */
#define SIGN_BIT (1UL << 63)
/* The bits that must be set to indicate a quiet NaN. */
#define QNAN (0x7ff8000000000000L)
/* If the NaN bits are set, it's not a number. */
#define IS_NUM(value) (((value).bits & QNAN) != QNAN)
/* Convert a raw number to a Value. */
#define NUM_VAL(n) ((Value)(double)(n))
/* Convert a Value representing a number to a raw double. */
#define AS_NUM(value) (value.num)
/* Converts a pointer to an Obj to a Value. */
#define OBJ_VAL(obj) ((Value)(SIGN_BIT | QNAN | (unsigned long)(obj)))
/* Converts a Value representing an Obj pointer to a raw Obj*. */
#define AS_OBJ(value) ((Obj*)((value).bits & ~(SIGN_BIT | QNAN)))
Но приведение к типу союза не является стандартом ANSI C89. Есть ли надежный способ для этого:
-std=c89 -pedantic
чистый?- Не противоречит строгим правилам псевдонимов?
Может использоваться в контексте выражения, как это:
Value value = ... printf("The number value is %f\n", AS_NUM(value));
'беззнаковое long' составляет 32 бита на многих системах. Вероятно, вы должны использовать 'uint64_t' из' stdint.h': к сожалению, это заголовок C99. – gsg
Почему вы хотите использовать 1989 C? Большинство компиляторов сегодня поддерживают как минимум C 1999, а слияние через союз поддерживается в C 1999 (tC3). ** Новое программное обеспечение не должно быть написано на старых, замененных языках **, если не существуют веские причины. –