views:

151

answers:

5

Hi,

The write function does not print a floating point number in the following code:

#include <unistd.h>

int main(){

    float f = 4.5;

    write(1,&f,sizeof float);

    return 0;
}

This results in:

�@

Whereas:

int main(){

    char *c = "Hello world";

    write (1,c,strlen(c)+1);

    return 0;
}

Prints Hello world as expected.

What am I missing?

Thanks in advance.

+4  A: 

write outputs the bytes in the binary representation of the floating-point number. Those bytes do not even always correspond to readable characters, let alone to the textual representation of the number itself.

I guess you want to convert the number to human-readable text. That's what printf is for:

printf("%f", f);
Thomas
Yes, but I cant use printf, must use write. So I guess i'll have to convert them to bytes ?
Tom
You can use sprintf, but that's just stupid. Why do you have to use write?
Lukáš Lalinský
Because I have to move this to assembly, using SYS_WRITE
Tom
I ended up avoiding the write from assembly and inserting the floating point values in an extern array. Then print them from C.
Tom
If this is linked to the C standard library, you can also call `printf` from your assembly. But I guess that calling it from C is easier :)
Thomas
A: 

Using write introduces dependency on endianness. So you might have to reverse the byte order when you read the file back in.

Otherwise, your code is perfectly fine. Did you try writing another program to read back in the same fashion, and compare the results?

The entire point of using write is to avoid conversion to text.

int main(){

    float f;

    read(0,&f,sizeof(float) );
    printf( "%f", (double) f );

    return 0;
}

Execute from the shell as

write_test | read_test
Potatoswatter
+3  A: 

Converting floating point numbers to strings is a far from trivial problem. See the famous Excel 2007 bug for an example of how even Microsoft got that wrong. You should use a library function such as snprintf(3) to convert the float to a string, and then you can use write(2) to write out the string:

float f = 4.5f;
char buf[64];
snprintf(buf, sizeof(buf), "%g", f);
write(1, buf, strlen(buf));
Adam Rosenfield
Thanks , this gave me a nice idea.
Tom
I ended up avoiding the write from assembly and inserting the floating point values in an extern array. Then print them from C.
Tom
A: 

You cat use obsolete function gcvt() to convert the case with float to your case with string:

#include <stdlib.h>
#include <stdio.h>

int main()
{
        char buffer[11];

        gcvt(3.1425, 3, buffer);
        buffer[10]=0;

        write(1, buffer,strlen(buffer)+1);

        return 0;
}

But snprintf() is preferable to use.

oraz
A: 

Look around for an implementation of ftoa. As mentioned by others, converting from floating point to a string representation is not a trivial task. Attempting to do so from assembly will be quite a challenge.

tomlogic