ESQL/C and double values
Posted in 1999
HELLO All!
I've big troubles running ESQL/C programs built in LINUX when these programs
communicate with an IDN engine that is running in HP-UX environment. In this
case, values defined as SQL FLOAT ( C type is double ) are read from the
database cutting some bits in the HEX representation and then spoiling them.
These values are inserted with tihese bits off so that if you try to access
them using their values in a WHERE clause you can't find the related rows.
Any hint ?
Peter
Attached is a sample C program that demonstrate the error:
/*
Test00.ec - trying to insert and re-read 27 double values
=========================================================
to build use:
export INFORMIXDIR=/usr/informix esql -I/usr/informix/incl/esql -static -o test00 test00.ec
execute the program simply calling it.
TYPICAL OUTPUT:
Line n.1 (1)
1.1 ttest1 = (100.000000) 00 00 00 00 00 00 59 40
Correct = (100.000000) 00 00 00 00 00 00 59 40
1.2 ttest2 = (10000.000000) fb ff ff ff ff 87 c3 40
Correct = (10000.000000) 00 00 00 00 00 88 c3 40
1.3 ttest3 = (100000.000000) f9 ff ff ff ff 69 f8 40
Correct = (100000.000000) 00 00 00 00 00 6a f8 40
Line n.2 (2)
2.1 ttest1 = (100.000000) 00 00 00 00 00 00 59 40
Correct = (100.000000) 00 00 00 00 00 00 59 40
2.2 ttest2 = (10000.000000) fb ff ff ff ff 87 c3 40
Correct = (10000.000000) 00 00 00 00 00 88 c3 40
2.3 ttest3 = (100000.000000) f9 ff ff ff ff 69 f8 40
Correct = (100000.000000) 00 00 00 00 00 6a f8 40
Line n.3 (3)
3.1 ttest1 = (200.000000) fd ff ff ff ff ff 68 40
Correct = (200.000000) 00 00 00 00 00 00 69 40
3.2 ttest2 = (20000.000000) fb ff ff ff ff 87 d3 40
Correct = (20000.000000) 00 00 00 00 00 88 d3 40
3.3 ttest3 = (200000.000000) f9 ff ff ff ff 69 08 41
Correct = (200000.000000) 00 00 00 00 00 6a 08 41
Line n.4 (4)
4.1 ttest1 = (600.000000) fe ff ff ff ff bf 82 40
Correct = (600.000000) 00 00 00 00 00 c0 82 40
4.2 ttest2 = (60000.000000) f9 ff ff ff ff 4b ed 40
Correct = (60000.000000) 00 00 00 00 00 4c ed 40
4.3 ttest3 = (600000.000000) fb ff ff ff 7f 4f 22 41
Correct = (600000.000000) 00 00 00 00 80 4f 22 41
Line n.5 (5)
5.1 ttest1 = (2400.000000) fe ff ff ff ff bf a2 40
Correct = (2400.000000) 00 00 00 00 00 c0 a2 40
5.2 ttest2 = (240000.000000) f5 ff ff ff ff 4b 0d 41
Correct = (240000.000000) 00 00 00 00 00 4c 0d 41
5.3 ttest3 = (2400000.000000) f9 ff ff ff 7f 4f 42 41
Correct = (2400000.000000) 00 00 00 00 80 4f 42 41
Line n.6 (6)
6.1 ttest1 = (12000.000000) fb ff ff ff ff 6f c7 40
Correct = (12000.000000) 00 00 00 00 00 70 c7 40
6.2 ttest2 = (1200000.000000) f7 ff ff ff 7f 4f 32 41
Correct = (1200000.000000) 00 00 00 00 80 4f 32 41
6.3 ttest3 = (12000000.000000) f5 ff ff ff 5f e3 66 41
Correct = (12000000.000000) 00 00 00 00 60 e3 66 41
Line n.7 (7)
7.1 ttest1 = (72000.000000) fc ff ff ff ff 93 f1 40
Correct = (72000.000000) 00 00 00 00 00 94 f1 40
7.2 ttest2 = (7200000.000000) f5 ff ff ff 3f 77 5b 41
Correct = (7200000.000000) 00 00 00 00 40 77 5b 41
7.3 ttest3 = (72000000.000000) f9 ff ff ff 87 2a 91 41
Correct = (72000000.000000) 00 00 00 00 88 2a 91 41
Line n.8 (8)
8.1 ttest1 = (504000.000000) f8 ff ff ff ff c2 1e 41
Correct = (504000.000000) 00 00 00 00 00 c3 1e 41
8.2 ttest2 = (50400000.000000) f5 ff ff ff 57 08 88 41
Correct = (50400000.000000) 00 00 00 00 58 08 88 41
8.3 ttest3 = (503999999.999999) f1 ff ff ff 6d 0a be 41
Correct = (504000000.000000) 00 00 00 00 6e 0a be 41
Line n.9 (9)
9.1 ttest1 = (4032000.000000) f5 ff ff ff ff c2 4e 41
Correct = (4032000.000000) 00 00 00 00 00 c3 4e 41
9.2 ttest2 = (403199999.999999) f5 ff ff ff 57 08 b8 41
Correct = (403200000.000000) 00 00 00 00 58 08 b8 41
9.3 ttest3 = (4031999999.999992) f0 ff ff ff 6d 0a ee 41
Correct = (4032000000.000000) 00 00 00 00 6e 0a ee 41
Test ENVIRONMENT:
Client built with:
INFORMIX EMBEDDED SQL for C Version 9.16.UC2
Copyright (C) 1991-1998 Informix Software, Inc.
PLATFORM: SuSE Linux kernel 2.0.36 largefd
Server:
Informix Dynamic Server Version 7.30.UC3
Copyright (C) 1986-1998 Informix Software, Inc.
PLATFORM: HP-UX rel. 10.20
*/
#include <stdio.h>
#include <stdarg.h>
EXEC SQL include sqlda;
static int err( long eno,char *fmt, ... )
{
va_list ap;
if(!eno || eno==SQLNOTFOUND )
return((int)eno);
va_start(ap,fmt);
fprintf(stderr,"SQL Error #%ld ",sqlca.sqlcode);
vfprintf(stderr,fmt,ap);
fprintf(stderr,"\\n");
fflush(stderr);
va_end(ap);
exit(-1);
}
static void dbldbg( double *dp )
{
unsigned char *up=(unsigned char *)dp;
fprintf(stderr,"\\t %02x %02x %02x %02x %02x %02x %02x %02x ",
(int)(up[0]&0xff), (int)(up[1]&0xff), (int)(up[2]&0xff),
(int)(up[3]&0xff), (int)(up[4]&0xff), (int)(up[5]&0xff),
(int)(up[6]&0xff), (int)(up[7]&0xff));
return;
}
EXEC SQL BEGIN DECLARE SECTION;
static long ttest0;
static double ttest1;
static double ttest2;
static double ttest3;
EXEC SQL END DECLARE SECTION;
void main( int ac,char *av[],char *ev[] )
{
int k;
double dbf[3];
EXEC SQL database test;
(void)err(sqlca.sqlcode,"Database test");
EXEC SQL create temp table ttest ( ttest0 serial not null,
ttest1 float,ttest2 float,ttest3 float) with no log;
(void)err(sqlca.sqlcode,"Create temp table ttest");
dbf[0]=100;
dbf[1]=10000.0;
dbf[2]=100000.0;
for( k=1;k<10;k++ )
{
ttest1 = dbf[0];
ttest2 = dbf[1];
ttest3 = dbf[2];
dbf[0] *= k;
dbf[1] *= k;
dbf[2] *= k;
EXEC SQL insert into ttest (
ttest0,ttest1,ttest2,ttest3
) values (
0,:ttest1,:ttest2,:ttest3
);
(void)err(sqlca.sqlcode,"Line #%d insert",k);
}
EXEC SQL declare c1 cursor for select
ttest0,ttest1,ttest2,ttest3
into
:ttest0,:ttest1,:ttest2,:ttest3
from ttest
order by 1;
(void)err(sqlca.sqlcode,"DECLARE c1");
EXEC SQL open c1;
(void)err(sqlca.sqlcode,"OPEN c1");
dbf[0]=100;
dbf[1]=10000.0;
dbf[2]=100000.0;
for(k=1;;k++)
{
EXEC SQL fetch c1;
if(err(sqlca.sqlcode,"FETCH c1"))
break;
fprintf(stderr,"Line n.%d (%ld)\\n",k,ttest0);
fprintf(stderr,"%2d.1 ttest1 = (%f) ",k,ttest1);
dbldbg( &ttest1 );fprintf(stderr,"\\n");
fprintf(stderr," Correct = (%f) ",dbf[0]);
dbldbg( &dbf[0] );fprintf(stderr,"\\n\\n");
fprintf(stderr,"%2d.2 ttest2 = (%f) ",k,ttest2);
dbldbg( &ttest2 );fprintf(stderr,"\\n");
fprintf(stderr," Correct = (%f) ",dbf[1]);
dbldbg( &dbf[1] );f