libgcc中读取了一些代码:
UDWtype __fixunsxfDI (XFtype a)
{
if (a < 0) return 0; /* Compute high word of result, as a flonum. */ const XFtype b = (a / Wtype_MAXp1_F); /* Convert that to fixed (but not to DWtype!), and shift it into the high word. */ UDWtype v = (UWtype) b; v <<= W_TYPE_SIZE; /* Remove high part from the XFtype, leaving the low part as flonum. */ a -= (XFtype)v; /* Convert that to fixed (but not to DWtype!) and add it in. Sometimes A comes out negative. This is significant, since A has more bits than a long int does. */ if (a < 0) v -= (UWtype) (- a); else v += (UWtype) a; return v; }
关于XFType:
typedef float XFtype __attribute__ ((mode (XF)));
关于Wtype_MAXp1_F:
#if W_TYPE_SIZE == 8 # define Wtype_MAXp1_F 0x1p8f #elif W_TYPE_SIZE == 16 # define Wtype_MAXp1_F 0x1p16f #elif W_TYPE_SIZE == 32 # define Wtype_MAXp1_F 0x1p32f #elif W_TYPE_SIZE == 64 # define Wtype_MAXp1_F 0x1p64f #else # error "expand the table" #endif
其中Wtype_MAXp1_F定义了 “0x1p8f” 、“0x1p16f”、“0x1p32f”、“0x1p64f”,四种不同的值。
举例来说“0x1p32f” p后面表示是2的32次方 并且类型为float,即0x1p32f=1*232
0x之后,p之前的数字被解释为十六进制数字并且可以包括小数点,即可以是整数也可以是小数。
在“0x2.3p-1”中,“2.3”表示2 + 3/16 = 2.1875 (转为10进制数),0x2.3p-1=2.1875*2-1=1.09375
所以,0x1p32f=1*232
其中“f”或“F”表是float类型,“l”或“L”表示long double
当a/Wtype_MAXp1_F 即 a除以2的(8/16/32/64)次方后,可以成为扩展精度算术的一部分;它将a分成一些“高位”和一些“低位”。
实际项目会用到a/Wtype_MAXp1_F的情况,用于转换16进制变量。如用vs编译,建议用vs2017以上,以下貌似不支持(未验证)
可以通过包含<float.h>并使用FLT_MAX获得最大有限float,DBL_MAX获得最大有限double来获得最大有限浮点数,并使用LDBL_MAX获得最大有限long double。
这些值远大于Wtype_MAXp1_F。还可以通过包含<math.h>和使用INFINITY获得最高的float值,即无穷大。