• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // commit: f657fe4b9f734d7fdea515af8dffbf7c28ce4fbc 2013-09-05
2 // classify invalid x86 ld80 representations (this is ub, we follow the fpu)
3 // test printf("%La") as well
4 #include <math.h>
5 #include <float.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include "test.h"
10 
11 #if LDBL_MANT_DIG==64
strclass(int c)12 static char *strclass(int c)
13 {
14 #define C(n) case n: return #n;
15 	switch (c) {
16 	C(FP_NAN)
17 	C(FP_INFINITE)
18 	C(FP_ZERO)
19 	C(FP_SUBNORMAL)
20 	C(FP_NORMAL)
21 	}
22 	return "invalid";
23 }
24 
25 #define T(f, desc, c, cwant, s, swant) do{ \
26 	c = fpclassify(f); \
27 	if (c != cwant) \
28 		t_error("fpclassify(%s) failed: got %s want %s\n", desc, strclass(c), #cwant); \
29 	memset(s, 0, sizeof(s)); \
30 	if (snprintf(s, sizeof(s), "%La", f) >= sizeof(s)) \
31 		t_error("snprintf(\"%%La\", %s) failed with invalid return value\n", desc); \
32 	if (strcmp(s,swant) != 0) \
33 		t_error("snprintf(\"%%La\", %s) failed: got \"%.*s\" want %s\n", desc, sizeof(s), s, #swant); \
34 }while(0)
35 
main(void)36 int main(void)
37 {
38 	union {
39 		long double f;
40 		struct {
41 			uint64_t m;
42 			uint16_t se;
43 		} i;
44 	} u;
45 	int c;
46 	int r;
47 	char s[32];
48 
49 	u.f = 0;
50 	u.i.m = (uint64_t)1<<63;
51 	T(u.f, "zero with msb set", c, FP_NORMAL, s, "0x1p-16382");
52 	u.i.m++;
53 	T(u.f, "subnormal with msb set", c, FP_NORMAL, s, "0x1.0000000000000002p-16382");
54 	u.f=1;
55 	u.i.m=0;
56 	T(u.f, "normal with msb unset", c, FP_NAN, s, "nan");
57 	u.f=INFINITY;
58 	u.i.m=0;
59 	T(u.f, "infinity with msb unset", c, FP_NAN, s, "nan");
60 	u.f=NAN;
61 	u.i.m&=(uint64_t)-1/2;
62 	T(u.f, "nan with msb unset", c, FP_NAN, s, "nan");
63 	return t_status;
64 }
65 #else
main(void)66 int main(void)
67 {
68 	return 0;
69 }
70 #endif
71