1
2
3
4
5
6
7
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <float.h>
13#include <fenv.h>
14
15
16#include "float_helpers.h"
17
18#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
19
20typedef struct {
21 int flag;
22 char *desc;
23} float_mapping;
24
25float_mapping round_flags[] = {
26 { FE_TONEAREST, "to nearest" },
27#ifdef FE_UPWARD
28 { FE_UPWARD, "upwards" },
29#endif
30#ifdef FE_DOWNWARD
31 { FE_DOWNWARD, "downwards" },
32#endif
33 { FE_TOWARDZERO, "to zero" }
34};
35
36static void print_input(float input)
37{
38 char *in_fmt = fmt_f32(input);
39 printf("from single: %s\n", in_fmt);
40 free(in_fmt);
41}
42
43static void convert_single_to_double(float input)
44{
45 double output;
46 char *out_fmt, *flag_fmt;
47
48 feclearexcept(FE_ALL_EXCEPT);
49
50 output = input;
51
52 out_fmt = fmt_f64(output);
53 flag_fmt = fmt_flags();
54 printf(" to double: %s (%s)\n", out_fmt, flag_fmt);
55 free(out_fmt);
56 free(flag_fmt);
57}
58
59#define xstr(a) str(a)
60#define str(a) #a
61
62#define CONVERT_SINGLE_TO_INT(TYPE, FMT) \
63 static void convert_single_to_ ## TYPE(float input) \
64 { \
65 TYPE ## _t output; \
66 char *flag_fmt; \
67 const char to[] = "to " xstr(TYPE); \
68 feclearexcept(FE_ALL_EXCEPT); \
69 output = input; \
70 flag_fmt = fmt_flags(); \
71 printf("%11s: %" FMT " (%s)\n", to, output, flag_fmt); \
72 free(flag_fmt); \
73 }
74
75CONVERT_SINGLE_TO_INT( int32, PRId32)
76CONVERT_SINGLE_TO_INT(uint32, PRId32)
77CONVERT_SINGLE_TO_INT( int64, PRId64)
78CONVERT_SINGLE_TO_INT(uint64, PRId64)
79
80int main(int argc, char *argv[argc])
81{
82 int i, j, nums;
83
84 nums = get_num_f32();
85
86 for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
87 if (fesetround(round_flags[i].flag) != 0) {
88 printf("### Rounding %s skipped\n", round_flags[i].desc);
89 continue;
90 }
91 printf("### Rounding %s\n", round_flags[i].desc);
92 for (j = 0; j < nums; j++) {
93 float input = get_f32(j);
94 print_input(input);
95
96 convert_single_to_double(input);
97 convert_single_to_int32(input);
98 convert_single_to_int64(input);
99 convert_single_to_uint32(input);
100 convert_single_to_uint64(input);
101 }
102 }
103
104 return 0;
105}
106