0

Let's say I have this float:

float f;

And I want to store it in a char array:

char bytes[4];

And then reverse the array back to float. Any help? Thanks in advance.

EDIT: Here is the code AND IT WORKS:

float amount = 0.01;
char array[sizeof(float)];
memcpy(array, &amount, sizeof(float));

float f;
char bytes[4] = {array[0], array[1], array[2], array[3]};
memcpy(&f, bytes, sizeof f);
5
  • 1
    By “reverse” to you mean simply move the bytes from the array back to the float or do you mean reverse the order of the bytes, making the last byte first, the first last, and so on? Commented Aug 16, 2019 at 15:57
  • You can try with C library function - atof() Commented Aug 16, 2019 at 16:11
  • @EricPostpischil I mean simply move the bytes from the array back to the float. Commented Aug 16, 2019 at 17:04
  • @ButiriDan I need to store it, not present it. Commented Aug 16, 2019 at 17:05
  • The code posted in the edit works for me, with printf("%g\n", f); appended to it (and also wrapped in #include <stdio.h> / #include <string.h>` / int main(void) { … }). It prints “0.01”. Commented Aug 16, 2019 at 17:55

4 Answers 4

4

Supposing that sizeof(float) is 4, you can copy the representation of the value of a float variable into a char array via memcpy:

#include <string.h>

void do_something(float f) {
    char bytes[4];
    memcpy(bytes, &f, 4);
    // ...
}

You can reverse that operation (that is, copy the representation back) by calling memcpy() again, with the first two arguments reversed. In between, you can manipulate the bytes -- for example, to reverse them -- but in that case, the language does not speak to the float interpretation of the resulting byte sequence.

Sign up to request clarification or add additional context in comments.

2 Comments

Does that mean that there is no way to do what I am asking?
@evannemo, you'll have to clarify what you are asking, per the comments on your question, but if I've understood correctly what that is then I believe this answer describes exactly how to do it.
1

You can use memcpy, but it is good to include a _Static_assert to check the sizes:

#include <stdio.h>
#include <string.h>

int main(void)
{
    float f = 10./7;
    char  bytes[4];

    // Check that float is the same size as the array we provide.
    _Static_assert(sizeof f == sizeof bytes, "float mus be four bytes.");

    // Copy bytes from the float to the array.
    memcpy(bytes, &f, sizeof bytes);

    // Show the bytes.
    for (size_t i = 0; i < sizeof bytes; ++i)
        printf("Byte %zu is 0x%02x.\n", i, (unsigned char) bytes[i]);

    // Copy the bytes from the array to another float.
    float g;
    memcpy(&g, bytes, sizeof g);

    // Show the resulting float.
    printf("g = %g.\n", g);
}

2 Comments

While the copy from float to char array works, the reverse doesn't work. I keep getting 0.0 at the printf.
@evannemo: The code was likely altered when you copied it. I compiled and executed before posting. And after; I copied the code from the web page and compiled and executed, and it prints “g = 1.42857.”
0
  • To convert float to char array sprintf
  • To convert char array to float atof
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char array[10];
    float val;

    sprintf(array, "%f", 3.123);
    val = atof(array);

    printf("%s\n%f", array, val);

    return 0;
}

Output

3.123000
3.123000

Comments

-2

memcpy is a built-in function requiring the header "string.h". Depending on your application scenario, if you want to avoid the use of memcpy plus your char array is 4-byte aligned, here is my preferred way based on static casting in gcc-like compilers.

Copy amount (float) to array (char*)

float amount  = 0.01;
char  array[4] __attribute__((aligned(4)));
*((float *)array) = amount; 

Copy bytes (char*) to f (float)

float f;
char bytes[4] __attribute__((aligned(4)));
f =  *((float *) bytes);

Alternatively, here is one more way that I believe will work under any compilers, regardless of byte alignment:

First, define a dummy struct with four bytes (a float takes four bytes. or alternatively, use sizeof(float) in place of 4).

typedef struct {char fourBytes[4]; } FourBytes ; 

Use it as follows:

float amount     = 0.01;
char  array[4]  ;

// copy from amount to array
*((FourBytes *)array) = *((FourBytes *) (&amount));

// copy from array to amount
 *((FourBytes *) (&amount)) = *((FourBytes *)array) ;

From a functional perspective, a third alternative may be just to use a union structure:

union DATA
{
    float f;
    char  array[4];
}; // array is forced to 4-byte aligned

Use it as follows:

union DATA data1;
union DATA data2;

// copy data between the two
data1.f = data2.f

2 Comments

And that specifically is invalid. Your cast has undefined behaviour, due to possible unaligned access and strict aliasing violation - the correct way is to use either a loop or a memcpy. The compiler knows how to optimize memcpy away if it can.
You are definitely right. The char array should be 4-byte aligned. A strict aliasing violation warning will be issued. I still keep the answer here and just in case, it may be relevant in some scenarios, yet with the caveats in mind

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.