Trivial question about storing floats

Discussion in 'C Programming' started by Jim, Dec 10, 2007.

  1. Jim

    Jim Guest

    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
    --
    http://www.ursaMinorBeta.co.uk

    "The Sierpinski Gasket makes me want to cry."
    - Jonathon Coulton, "Mandelbrot Set"
     
    Jim, Dec 10, 2007
    #1
    1. Advertising

  2. On Mon, 10 Dec 2007 10:29:36 +0000,
    Jim <> wrote:

    [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
    --
    |
    Martien Verbruggen | Useful Statistic: 75% of the people make up
    | 3/4 of the population.
    |
     
    Martien Verbruggen, Dec 10, 2007
    #2
    1. Advertising

  3. Jim

    Jim Guest

    On 2007-12-10, Martien Verbruggen <> wrote:
    > On Mon, 10 Dec 2007 10:29:36 +0000,
    > Jim <> wrote:
    >
    > [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
    --
    http://www.ursaMinorBeta.co.uk

    "The Sierpinski Gasket makes me want to cry."
    - Jonathon Coulton, "Mandelbrot Set"
     
    Jim, Dec 10, 2007
    #3
  4. Jim

    pete Guest

    Jim wrote:
    >
    > 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 */

    --
    pete
     
    pete, Dec 10, 2007
    #4
  5. Jim

    Mark Bluemel Guest

    Martien Verbruggen wrote:
    > On Mon, 10 Dec 2007 10:29:36 +0000,
    > Jim <> wrote:
    >
    > [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)
     
    Mark Bluemel, Dec 10, 2007
    #5
  6. Jim

    pete Guest

    pete wrote:
    >
    > Jim wrote:
    > >
    > > 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);
    > }


    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.

    --
    pete
     
    pete, Dec 10, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Timbers
    Replies:
    32
    Views:
    1,443
    Alvin Bruney
    Nov 8, 2003
  2. Kosio

    Floats to chars and chars to floats

    Kosio, Sep 16, 2005, in forum: C Programming
    Replies:
    44
    Views:
    1,347
    Tim Rentsch
    Sep 23, 2005
  3. baibaichen

    trivial or non-trivial object

    baibaichen, Jan 12, 2006, in forum: C++
    Replies:
    3
    Views:
    957
    osmium
    Jan 12, 2006
  4. toton
    Replies:
    11
    Views:
    742
    toton
    Oct 13, 2006
  5. Jonathan Wood
    Replies:
    1
    Views:
    531
    Jonathan Wood
    Jun 2, 2008
Loading...

Share This Page