Skip to content
Snippets Groups Projects
bytedouble.c 1.87 KiB
Newer Older
/*
 * SPDX-FileCopyrightText: 2020 Bruce Cowan <bruce@bcowan.me.uk>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
Bruce Cowan's avatar
Bruce Cowan committed

#include <endian.h>
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
Bruce Cowan's avatar
Bruce Cowan committed
#include <stdio.h>
#include <string.h>
Bruce Cowan's avatar
Bruce Cowan committed
typedef union
{
  uint8_t bytes[sizeof (double)];
  double  d;
} DoubleBytes;
Bruce Cowan's avatar
Bruce Cowan committed
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)
Bruce Cowan's avatar
Bruce Cowan committed
  uint64_t ret = be64toh ((uint64_t) * (uint64_t *) bytes);
  memcpy (bytes, &ret, 8);
}
Bruce Cowan's avatar
Bruce Cowan committed
static void
double_to_be_bytes (double   d,
                    uint8_t *bytes)
{
  DoubleBytes db;
  db.d = d;
Bruce Cowan's avatar
Bruce Cowan committed
  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 [");

Bruce Cowan's avatar
Bruce Cowan committed
    for (size_t i = 0; i < len-1; i++)
        printf ("%02" PRIx8 ", ", bytes[i]);

Bruce Cowan's avatar
Bruce Cowan committed
    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));
Bruce Cowan's avatar
Bruce Cowan committed
    double d = be_bytes_to_double (bytes);
    printf ("Converting back, the value is %.15g\n", d);