From 8df8dd368490573370bf1d2e7fe89d527ea7f96d Mon Sep 17 00:00:00 2001 From: Bruce Cowan <bruce@bcowan.me.uk> Date: Sun, 21 Jun 2020 12:06:31 +0100 Subject: [PATCH] Port to using endian.h --- meson.build | 7 ++-- src/bytedouble.c | 93 +++++++++++++++++++++++++++++++++++++++++------- src/meson.build | 5 ++- 3 files changed, 90 insertions(+), 15 deletions(-) diff --git a/meson.build b/meson.build index 978ed8f..13bb802 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,4 @@ -# SPDX-FileCopyrightText: 2018, 2019 Bruce Cowan -# +# SPDX-FileCopyrightText: 2018-2020 Bruce Cowan # SPDX-License-Identifier: CC0-1.0 project('stdlib', 'c', @@ -18,6 +17,10 @@ if cc.has_function('reallocarray', prefix: '#define _GNU_SOURCE\n#include <stdli conf_data.set('HAVE_REALLOCARRAY', 1) endif +if cc.has_header('endian.h') + has_endian_h = true +endif + configure_file(configuration: conf_data, output: 'config.h') config_dep = declare_dependency(include_directories: '.') diff --git a/src/bytedouble.c b/src/bytedouble.c index 35b9f65..daf6950 100644 --- a/src/bytedouble.c +++ b/src/bytedouble.c @@ -2,31 +2,100 @@ * SPDX-FileCopyrightText: 2020 Bruce Cowan <bruce@bcowan.me.uk> * SPDX-License-Identifier: Apache-2.0 */ + +#include <endian.h> +#include <errno.h> #include <inttypes.h> -#include <math.h> #include <stdint.h> -#include <stdio.h> #include <stdlib.h> +#include <stdio.h> +#include <string.h> -#define DOUBLE_TO_BYTES(d) ((uint8_t *) &(d)) -#define BYTES_TO_DOUBLE(b) (*((double *) (b))) +typedef union +{ + uint8_t bytes[sizeof (double)]; + double d; +} DoubleBytes; -int -main (void) +static void +bytes_to_be (uint8_t *bytes) +{ + uint64_t ret = htobe64 ((uint64_t) *(uint64_t *) bytes); + memcpy (bytes, &ret, 8); +} + +static void +bytes_from_be (uint8_t *bytes) { - double pi = M_PI; + uint64_t ret = be64toh ((uint64_t) * (uint64_t *) bytes); + memcpy (bytes, &ret, 8); +} - uint8_t *bytes = DOUBLE_TO_BYTES (pi); +static void +double_to_be_bytes (double d, + uint8_t *bytes) +{ + DoubleBytes db; + db.d = d; + bytes_to_be (db.bytes); + memcpy (bytes, db.bytes, sizeof (double)); +} + +static double +be_bytes_to_double (uint8_t *bytes) +{ + DoubleBytes db; + memcpy (db.bytes, bytes, sizeof (double)); + bytes_from_be (db.bytes); + + return db.d; +} + +static void +print_bytes (uint8_t *bytes, + size_t len) +{ printf ("Bytes are ["); - for (int i = 0; i < 7; i++) + for (size_t i = 0; i < len-1; i++) printf ("%02" PRIx8 ", ", bytes[i]); - printf ("%02" PRIx8 "]\n", bytes[7]); + printf ("%02" PRIx8 "]\n", bytes[len-1]); +} + +int +main (void) +{ + errno = 0; + char buf[32]; + char *endptr; + + puts ("Please enter a floating point number"); + fgets (buf, 31, stdin); + double val = strtod (buf, &endptr); + if (errno) + { + perror ("strtod"); + return EXIT_FAILURE; + } + if (buf == endptr) + { + fputs ("No digits found\n", stderr); + return EXIT_FAILURE; + } + + uint8_t bytes[sizeof (double)]; + + memcpy (bytes, &val, sizeof (double)); + print_bytes (bytes, sizeof (double)); + + double_to_be_bytes (val, bytes); + puts ("After swapping:"); + print_bytes (bytes, sizeof (double)); - double d = BYTES_TO_DOUBLE (bytes); - printf ("Converting back, the value is %f\n", d); + double d = be_bytes_to_double (bytes); + printf ("Converting back, the value is %.15g\n", d); return 0; } diff --git a/src/meson.build b/src/meson.build index 2682858..4b20046 100644 --- a/src/meson.build +++ b/src/meson.build @@ -6,7 +6,6 @@ executable('angle', 'angle.c', dependencies: libm) executable('array-length', 'array-length.c', dependencies: types_dep) executable('binary', 'binary.c') executable('binary2', 'binary2.c', dependencies: utils_dep) -executable('bytedouble', 'bytedouble.c') executable('complex', 'complex.c', dependencies: libm) executable('doubles', 'doubles.c') executable('einstein', 'einstein.c') @@ -30,6 +29,10 @@ executable('world', 'world.c') subdir('sockets') +if has_endian_h + executable('bytedouble', 'bytedouble.c') +endif + if openmp_dep.found() subdir('openmp') endif -- GitLab