1 /* 2 * Floating Point Convert Single to Various 3 * 4 * Copyright (c) 2019 Linaro 5 * 6 * SPDX-License-Identifier: GPL-3.0-or-later 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 20 typedef struct { 21 int flag; 22 char *desc; 23 } float_mapping; 24 25 float_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 36 static 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 43 static 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 75 CONVERT_SINGLE_TO_INT( int32, PRId32) 76 CONVERT_SINGLE_TO_INT(uint32, PRId32) 77 CONVERT_SINGLE_TO_INT( int64, PRId64) 78 CONVERT_SINGLE_TO_INT(uint64, PRId64) 79 80 int 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 /* convert_single_to_half(input); */ 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