float_convs.c (2807B)
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 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#ifdef FE_TOWARDZERO 34 { FE_TOWARDZERO, "to zero" } 35#endif 36}; 37 38static void print_input(float input) 39{ 40 char *in_fmt = fmt_f32(input); 41 printf("from single: %s\n", in_fmt); 42 free(in_fmt); 43} 44 45static void convert_single_to_double(float input) 46{ 47 double output; 48 char *out_fmt, *flag_fmt; 49 50 feclearexcept(FE_ALL_EXCEPT); 51 52 output = input; 53 54 out_fmt = fmt_f64(output); 55 flag_fmt = fmt_flags(); 56 printf(" to double: %s (%s)\n", out_fmt, flag_fmt); 57 free(out_fmt); 58 free(flag_fmt); 59} 60 61#define xstr(a) str(a) 62#define str(a) #a 63 64#define CONVERT_SINGLE_TO_INT(TYPE, FMT) \ 65 static void convert_single_to_ ## TYPE(float input) \ 66 { \ 67 TYPE ## _t output; \ 68 char *flag_fmt; \ 69 const char to[] = "to " xstr(TYPE); \ 70 feclearexcept(FE_ALL_EXCEPT); \ 71 output = input; \ 72 flag_fmt = fmt_flags(); \ 73 printf("%11s: %" FMT " (%s)\n", to, output, flag_fmt); \ 74 free(flag_fmt); \ 75 } 76 77CONVERT_SINGLE_TO_INT( int32, PRId32) 78CONVERT_SINGLE_TO_INT(uint32, PRId32) 79CONVERT_SINGLE_TO_INT( int64, PRId64) 80CONVERT_SINGLE_TO_INT(uint64, PRId64) 81 82int main(int argc, char *argv[argc]) 83{ 84 int i, j, nums; 85 86 nums = get_num_f32(); 87 88 for (i = 0; i < ARRAY_SIZE(round_flags); ++i) { 89 if (fesetround(round_flags[i].flag) != 0) { 90 printf("### Rounding %s skipped\n", round_flags[i].desc); 91 continue; 92 } 93 printf("### Rounding %s\n", round_flags[i].desc); 94 for (j = 0; j < nums; j++) { 95 float input = get_f32(j); 96 print_input(input); 97 /* convert_single_to_half(input); */ 98 convert_single_to_double(input); 99 convert_single_to_int32(input); 100 convert_single_to_int64(input); 101 convert_single_to_uint32(input); 102 convert_single_to_uint64(input); 103 } 104 } 105 106 return 0; 107}