Arthur Green
Arthur Green

Reputation: 146

C programming Printing a float as long double in hex

I am creating a program for homework, and the goal is trying to teach us how a union works conceptually. I believe I understand this concept, but I am having difficulty with one of my outputs; Long Double as Hex.

I am under the assumption anything long needs a capital L after the percent sign when printing. For example to print a long double float:

printf("\nLong double: %Lf\n", value.ld);

Similarly, if I wanted to print a Long Double float in hex I would use:

printf("\nLong double: %Lx", value.ld);

My professor's output is as follows:

Professors Output long double 22fde0

My Output is as follows:

My Output long double 62fe40

The differences are in the printed value for Long Double in hex. Is this a value that might be different from computer to computer or am I making a mistake in my thinking.

My code

#include <stdio.h>

// define union data
    union data {
        float f;
        double d;
        long double ld;
    }value; //union variable

// begin main function
int main(void){

    // get initial user input
    printf("Enter data for type float: ");
    scanf(" %f", &value.f);

    puts("\nBreakdown of the element in the union: ");
    printf("Float: %f", value.f);
    printf("\nDouble: %f", value.d);
    printf("\nLong double: %Lf\n", value.ld);

    puts("\nBreakdown in hex: ");
    printf("Float: %x", value.f);
    printf("\nDouble: %x", value.d);
    printf("\nLong double: %Lx", value.ld);

    // get user input
    printf("\n\nEnter data for type double: ");
    scanf(" %lf", &value.d);

    puts("\nBreakdown of the element in the union: ");
    printf("Float: %f", value.f);
    printf("\nDouble: %f", value.d);
    printf("\nLong double: %Lf\n", value.ld);

    puts("\nBreakdown in hex: ");
    printf("Float: %x", value.f);
    printf("\nDouble: %x", value.d);
    printf("\nLong double: %Lx", value.ld);

    // get user input
    printf("\n\nEnter data for type long double: ");
    scanf(" %lf", &value.ld);

    puts("\nBreakdown of the element in the union: ");
    printf("Float: %f", value.f);
    printf("\nDouble: %f", value.d);
    printf("\nLong double: %Lf\n", value.ld);

    puts("\nBreakdown in hex: ");
    printf("Float: %x", value.f);
    printf("\nDouble: %x", value.d);
    printf("\nLong double: %Lx", value.ld);

    return 0;
} // end main function

Upvotes: 1

Views: 2304

Answers (3)

Heath Raftery
Heath Raftery

Reputation: 4169

Is this a value that might be different from computer to computer

Definitely. It's not at all clear what your professor meant by "long double as hex". If you do as you've done, passing a long double to the %x specifier, then you get undefined behaviour - the %x specifier expects an integer (or variant) and it's not easy to predict what will happen if you pass it a float (or variant).

If you use the %a specifier, which is explicitly for printing floats in hex, then you get a hex representation of the floating point value, not the contents of memory. So, for example 1.5 would be printed as 0x1.8p+0 because .8 is hexadecimal for .5 in decimal.

If what you really want is the contents of memory, as hex, then you need to pass the %x specifier an integer. Easiest way to do that is add appropriate integer types to your union.

union data {
        float f;
        int i;
        double d;
        long int li;
        long double ld;
        long long int lli;
    }value; //union variable

Then, if you want the memory contents in hex of a double, for example, just use:

// get user input
printf("\n\nEnter data for type double: ");
scanf(" %f", &value.d);

puts("\nBreakdown of the element in the union: ");
printf("Double: %f", value.d);
printf("Hex: %lx", value.li);

By the way, %l... (lowercase ell) is for integers, %L... (uppercase ell) is for float types. A long int is typically the same size as a double on 64 bit platforms (but not guaranteed to be so!). %f, somewhat confusingly, is for a double argument. There is no specifier for floats - they are automatically promoted to doubles.

Upvotes: 1

duong_dajgja
duong_dajgja

Reputation: 4276

Please use union, as pointed in how to print float in hex format in C?

Here is what I grabbed from the link:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <math.h>

int main (void) {

    float pi = (float)M_PI;
    union {
        float f;
        uint32_t u;
    } f2u = { .f = pi };

    printf ("pi (floating point): %f\n", pi);
    printf ("pi (hex representation): 0x%\n", f2u.u);

    return 0;
}

Output:

$ ./bin/float_hex
pi (floating point) : 3.141593
pi (hex representation): 0x40490fdb

Upvotes: 0

dbush
dbush

Reputation: 224437

The %x format specifier is expecting an integer type to be printed in hex. Passing in a floating point type for this invokes undefined behavior.

You can print floating point numbers in hex with the %a format specifier:

printf("\nLong double: %La", value.ld);

Upvotes: 1

Related Questions