pg.ddx.io  pgsql-interfaces@postgresql.org mailing list archive  
help / color / mirror / Atom feed
libpq: PQexecParams, binaryFormat and float
3+ messages / 3 participants
[nested] [flat]

* libpq: PQexecParams, binaryFormat and float
@ 2007-06-29 19:09 Sun, Way <Way.Sun@sciatl.com>
  2007-06-29 20:27 ` Re: libpq: PQexecParams, binaryFormat and float Tom Lane <tgl@sss.pgh.pa.us>
  2007-07-09 22:46 ` Re: libpq: PQexecParams, binaryFormat and float Richard Frankland <rfrankla@yahoo.com>
  0 siblings, 2 replies; 3+ messages in thread

From: Sun, Way @ 2007-06-29 19:09 UTC (permalink / raw)
  To: pgsql-interfaces

Hi,

I'm having trouble inserting a float into pg using binary format. 

Hope someone on the list can help me point out what I'm doing wrong....

    float    loadavg;

    loadavg = htonl(1.23);

    paramValues[0] = (char *) &loadavg
    paramLengths[0] = sizeof(loadavg);
    paramFormats[0] = 1;        

    res = PQexecParams(conn,
                       "INSERT INTO cpu (loadavg) VALUES ($1::real)",
                       1,       
                       NULL,    
                       paramValues,
                       paramLengths,
                       paramFormats,
                       1);      

^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* Re: libpq: PQexecParams, binaryFormat and float
  2007-06-29 19:09 libpq: PQexecParams, binaryFormat and float Sun, Way <Way.Sun@sciatl.com>
@ 2007-06-29 20:27 ` Tom Lane <tgl@sss.pgh.pa.us>
  1 sibling, 0 replies; 3+ messages in thread

From: Tom Lane @ 2007-06-29 20:27 UTC (permalink / raw)
  To: Sun, Way <Way.Sun@sciatl.com>; +Cc: pgsql-interfaces

"Sun, Way" <Way.Sun@sciatl.com> writes:
>     float    loadavg;
>     loadavg = htonl(1.23);

It seems entirely unlikely that that will produce a byte-reversed float
value; what I think will happen is that the byte-reversed value of
integer 1 will be converted into a host-format float and stored into
loadavg.

AFAIK you can't really do this in C without a union.  Take a look at 
pq_sendfloat4 and pq_getmsgfloat4 in the backend for examples.

			regards, tom lane



^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* Re: libpq: PQexecParams, binaryFormat and float
  2007-06-29 19:09 libpq: PQexecParams, binaryFormat and float Sun, Way <Way.Sun@sciatl.com>
@ 2007-07-09 22:46 ` Richard Frankland <rfrankla@yahoo.com>
  1 sibling, 0 replies; 3+ messages in thread

From: Richard Frankland @ 2007-07-09 22:46 UTC (permalink / raw)
  To: Sun, Way <Way.Sun@sciatl.com>; pgsql-interfaces

Hi, This is my first reply/post to postgres forums. I hope I'm doing it OK.
If not, please help.

So, onto how I see the problem and a possible solution.
As Tom Lane pointed out. Using a "union" is another solution to this problem.

Here is a simple testing program and output:

#include <stdio.h>
/* for ntohl/htonl */
#include <netinet/in.h>

void show_hex (void * vptr) {
    unsigned char * xptr;
    int k;
    /* display each byte in heX */
    xptr = (unsigned char *)vptr;
    for (k=0; k<4; k++)
    {
        printf("%.2X  ", *(xptr+k));
    }
    printf("\n");
}

int
main(int argc, char **argv)
{
    float         starting_value = 1.23;
    float         loadavg;
    unsigned long reversed_float;

    /* prove we really are starting with 1.23 */
    printf( "%f \n", starting_value);
    show_hex(&starting_value);

    /* see man page for return type of htonl() */
    reversed_float = htonl(starting_value);
    show_hex(&reversed_float);
    
    /* implicit conversion shown explicitly (i.e. has no effect) */
    reversed_float = htonl((long)starting_value);
    show_hex(&reversed_float);
    
    /* and another implicit conversion */
    loadavg = reversed_float; //htonl(starting_value);
    show_hex(&loadavg);

    /* again, shown explicitly */ 
    loadavg = (float)(unsigned long)16777216; //htonl(starting_value);
    show_hex(&loadavg);
    loadavg = (float)(unsigned long)htonl((long)starting_value); //htonl(starting_value);
    show_hex(&loadavg);
    /* show what was stored into loadavg */
    printf( "%f \n", loadavg);

    /* show this is the same as the original problem */
    loadavg = htonl(1.23);
    printf( "%f \n", loadavg);

    /* A (not the only one) correct solution                   */
    /* Casting a pointer:                                      */
    /*                       address of source                 */
    /*                                       |                 */
    /* pointer to UNSIGNED type              |                 */
    /*                       |               |                 */
    /*   dereference pointer |               |                 */
    /*                     | |               |                 */
    /*                     | |               |                 */
    /*                     | |               |                 */
    reversed_float = htonl(*(unsigned long *)&starting_value);

    show_hex(&reversed_float);
    
    /*
     *   paramValues[0] = (unsigned char *) &reversed_float;
     */
}

------------------------------------------------------
$ ./tst
1.230000 
A4  70  9D  3F  
00  00  00  01  
00  00  00  01  
00  00  80  4B  
00  00  80  4B  
16777216.000000 
16777216.000000 
3F  9D  70  A4  
$




"Sun, Way" <Way.Sun@sciatl.com> wrote:     
 Hi,
 I'm having trouble inserting a float into pg using binary format. 
 Hope someone on the list can help me point out what I'm doing wrong....
     float    loadavg;
     loadavg = htonl(1.23);
     paramValues[0] = (char *) &loadavg
    paramLengths[0] = sizeof(loadavg);
    paramFormats[0] = 1;        
     res = PQexecParams(conn,
                       "INSERT INTO cpu (loadavg) VALUES ($1::real)",
                       1,       
                       NULL,    
                       paramValues,
                       paramLengths,
                       paramFormats,
                       1);      
 From psql, select returns the value as 1.20765e-38 instead of 1.23.....:(
 Thanks
 Way


 
---------------------------------
  
      - - - - - Appended by Scientific Atlanta, a Cisco company - - - - -         
This e-mail and any attachments may contain information which is confidential, 
proprietary, privileged or otherwise protected by law. The information is solely 
intended for the named addressee (or a person responsible for delivering it to 
the addressee). If you are not the intended recipient of this message, you are 
not authorized to read, print, retain, copy or disseminate this message or any 
part of it. If you have received this e-mail in error, please notify the sender 
immediately by return e-mail and delete it from your computer.

       
---------------------------------
Boardwalk for $500? In 2007? Ha! 
Play Monopoly Here and Now (it's updated for today's economy) at Yahoo! Games.

^ permalink  raw  reply  [nested|flat] 3+ messages in thread


end of thread, other threads:[~2007-07-09 22:46 UTC | newest]

Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2007-06-29 19:09 libpq: PQexecParams, binaryFormat and float Sun, Way <Way.Sun@sciatl.com>
2007-06-29 20:27 ` Tom Lane <tgl@sss.pgh.pa.us>
2007-07-09 22:46 ` Richard Frankland <rfrankla@yahoo.com>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox