Trivial question about storing floats

J

Jim

I recently had to extract some data from some data files handed to us. Part
of the data to extract was a floating point value representing a weight. As
we didn't have the file formats I had to guess where the float would be. As
I knew what the weight was on one record I decided to knock up a quick
programme to output the value 9.5 as a float so I could see where it was in
the other file. However, I'm doing something wrong.

The code I knocked up was this:



#include <stdio.h>

void main()
{
double f = 9.5;
FILE *outfile;

outfile=fopen("jim.test","wb");

fprintf(outfile, "%f", f );
fclose(outfile);
}


However, this produced the following file (hexdumped):

39 2E 35 30 30 30 30 30

which is literally '9.500000', when the actual byte stream should have been

00 00 18 41 (Intel)

So: what _should_ I have written in order to get the four-byte float in the
file instead of what appears to be the plain text version?

It's a moot point as I got the data anyway, but I'm curious.

Many thanks.

Jim
 
M

Martien Verbruggen

On Mon, 10 Dec 2007 10:29:36 +0000,

[snip]
#include <stdio.h>

void main()
{
double f = 9.5;
FILE *outfile;

outfile=fopen("jim.test","wb");

fprintf(outfile, "%f", f );
fclose(outfile);
}
So: what _should_ I have written in order to get the four-byte float in the
file instead of what appears to be the plain text version?

fwrite(&f, sizeof f, 1, outfile);

Note that it's possible that double is 4 bytes, but more likely 8. You
probably want float.

Martien
 
J

Jim

On Mon, 10 Dec 2007 10:29:36 +0000,

[snip]
#include <stdio.h>

void main()
{
double f = 9.5;
FILE *outfile;

outfile=fopen("jim.test","wb");

fprintf(outfile, "%f", f );
fclose(outfile);
}
So: what _should_ I have written in order to get the four-byte float in the
file instead of what appears to be the plain text version?

fwrite(&f, sizeof f, 1, outfile);

Oh good grief, yes, of course. Thanks. I'm so used to using fread/fwrite
with structs that I sometimes forget they're not obligatory :)
Note that it's possible that double is 4 bytes, but more likely 8. You
probably want float.

Yes, sorry, that code was after some diddling.

Thanks again.

Jim
 
P

pete

Jim said:
I recently had to extract some data from some data files handed to us. Part
of the data to extract was a floating point value representing a weight. As
we didn't have the file formats I had to guess where the float would be. As
I knew what the weight was on one record I decided to knock up a quick
programme to output the value 9.5 as a float so I could see where it was in
the other file. However, I'm doing something wrong.

The code I knocked up was this:

#include <stdio.h>

void main()
{
double f = 9.5;
FILE *outfile;

outfile=fopen("jim.test","wb");

fprintf(outfile, "%f", f );
fclose(outfile);
}

However, this produced the following file (hexdumped):

39 2E 35 30 30 30 30 30

which is literally '9.500000', when the actual byte stream should have been

00 00 18 41 (Intel)

So: what _should_ I have written in order
to get the four-byte float in the
file instead of what appears to be the plain text version?

It's a moot point as I got the data anyway, but I'm curious.

Many thanks.

/* BEGIN new.c */

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

int main(void)
{
double f = 9.5;
FILE *outfile;
size_t byte;
double target;
int rc;

assert(INT_MAX >= UCHAR_MAX);
outfile = fopen("jim.test","w");
if (outfile == NULL) {
puts("outfile == NULL");
exit(EXIT_FAILURE);
}
for (byte = 0; byte != sizeof f; ++byte) {
fputc(*((unsigned char *)&f + byte), outfile);
}
fclose(outfile);

outfile = fopen("jim.test","r");
if (outfile == NULL) {
puts("outfile == NULL");
exit(EXIT_FAILURE);
}
for (byte = 0; byte != sizeof f; ++byte) {
rc = getc(outfile);
if (rc == EOF) {
fclose(outfile);
puts("rc == EOF");
exit(EXIT_FAILURE);
}
*((unsigned char *)&target + byte) = (unsigned char)rc;
}
fclose(outfile);
printf("target is %f\n", target);
return 0;
}

/* END new.c */
 
M

Mark Bluemel

Martien said:
On Mon, 10 Dec 2007 10:29:36 +0000,

[snip]
#include <stdio.h>

void main()
{
double f = 9.5;
FILE *outfile;

outfile=fopen("jim.test","wb");

fprintf(outfile, "%f", f );
fclose(outfile);
}
So: what _should_ I have written in order to get the four-byte float in the
file instead of what appears to be the plain text version?

fwrite(&f, sizeof f, 1, outfile);

Note that it's possible that double is 4 bytes, but more likely 8. You
probably want float.

Note that this depends on the files you are processing having been
produced with a compatible float format...

See (e.g.) question 20.5 of the FAQ (http://www.c-faq.com)
 
P

pete

pete said:
/* BEGIN new.c */

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

int main(void)
{
double f = 9.5;
FILE *outfile;
size_t byte;
double target;
int rc;

assert(INT_MAX >= UCHAR_MAX);
outfile = fopen("jim.test","w");
if (outfile == NULL) {
puts("outfile == NULL");
exit(EXIT_FAILURE);
}
for (byte = 0; byte != sizeof f; ++byte) {
fputc(*((unsigned char *)&f + byte), outfile);
}

fputc('\n', outfile);
fclose(outfile);

outfile = fopen("jim.test","r");
if (outfile == NULL) {
puts("outfile == NULL_2");
exit(EXIT_FAILURE);
}
for (byte = 0; byte != sizeof f; ++byte) {
rc = getc(outfile);
if (rc == EOF) {
fclose(outfile);
puts("rc == EOF");
exit(EXIT_FAILURE);
}
*((unsigned char *)&target + byte) = (unsigned char)rc;
}

getc(outfile);
fclose(outfile);
printf("target is %f\n", target);
return 0;
}

/* END new.c */

I had neglected to terminate the text streams with newlines.
One never knows what might happen in such cases.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top