Подходя к этому поздно, но я подумал о другом подходе.
Если вы знаете, что ваша система использует формат с плавающей точкой IEEE754, но не знаете, насколько большие типы с плавающей точкой относятся к целочисленным типам, выможет сделать что-то вроде этого:
bool isFloatIEEE754Negative(float f)
{
float d = f;
if (sizeof(float)==sizeof(unsigned short int)) {
return (*(unsigned short int *)(&d) >> (sizeof(unsigned short int)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned int)) {
return (*(unsigned int *)(&d) >> (sizeof(unsigned int)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned long)) {
return (*(unsigned long *)(&d) >> (sizeof(unsigned long)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned char)) {
return (*(unsigned char *)(&d) >> (sizeof(unsigned char)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned long long)) {
return (*(unsigned long long *)(&d) >> (sizeof(unsigned long long)*CHAR_BIT - 1) == 1);
}
return false; // Should never get here if you've covered all the potential types!
}
По сути, вы обрабатываете байты в вашем float как целочисленный тип без знака, а затем смещаете вправо все биты (кроме знака) (кроме знака) из существования.'>>' работает независимо от порядка байтов, поэтому это позволяет обойти эту проблему.
Если можно определить до выполнения, какой целочисленный тип без знака имеет ту же длину, что и тип с плавающей запятой, вы можете сократить это:
#define FLOAT_EQUIV_AS_UINT unsigned int // or whatever it is
bool isFloatIEEE754Negative(float f)
{
float d = f;
return (*(FLOAT_EQUIV_AS_UINT *)(&d) >> (sizeof(FLOAT_EQUIV_AS_UINT)*CHAR_BIT - 1) == 1);
}
Это работало на моих тестовых системах;Кто-нибудь видел какие-либо предостережения или упускали из виду «Гочас»?