RE: Possible bug regarding endiannes and realstorageclass (sqlite3)

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

RE: Possible bug regarding endiannes and realstorageclass (sqlite3)

Thomas Briggs

   I can also confirm that the original test case posted works correctly
when moving the file from Linux to Sparc (Solaris) and PA-RISC (HP-UX).

   -Tom

> -----Original Message-----
> From: D. Richard Hipp [mailto:[hidden email]]
> Sent: Thursday, August 18, 2005 2:21 PM
> To: [hidden email]
> Subject: Re: [sqlite] Possible bug regarding endiannes and
> realstorageclass (sqlite3)
>
> On Thu, 2005-08-18 at 14:10 -0400, D. Richard Hipp wrote:
> > On Thu, 2005-08-18 at 09:40 -0700, Robert Simpson wrote:
> > > http://www.psc.edu/general/software/packages/ieee/ieee.html
> > >
> > > The way I interpreted this site, is that the IEEE
> standard for floating
> > > point numbers was processor agnostic and the storage of
> the bits went from
> > > left to right.
> > >
> >
> > I wrote a test program to print out the byte values for 1.0 and 1
> > on both ix86 (Intel, Linux) and powerpc (G5, OS-X).  The results:
> >
> >     ix86:   000000000000f03f  0100000000000000
> >  powerpc:   3ff0000000000000  0000000000000001
> >
> > This seems to validate the approach taken by SQLite, which is to
> > byteswap floating point values on ix86 machines.
> >
>
> As a double-check, I have confirmed that floating-point values
> written into an SQLite3 database file written on intel/linux
> are readable on max/os-x and vice versa.
> --
> D. Richard Hipp <[hidden email]>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Possible bug regarding endiannes and realstorageclass (sqlite3)

Frank van Vugt
I repeated the test using the value 1.2345678 in order to be able to identify
the position of each byte:

linux i386:

1bde8342cac0f33f
0100000000000000



linux arm:

cac0f33f1bde8342
0100000000000000



So, it indeed looks like 32bits based middle-endian or something




--
Best,




Frank.
Reply | Threaded
Open this post in threaded view
|

Re[2]: Possible bug regarding endiannes and realstorageclass (sqlite3)

Doug Currie-2
Thursday, August 18, 2005, 3:18:56 PM, Frank wrote:

> I repeated the test using the value 1.2345678 in order to be
> able to identify the position of each byte:

> linux i386:

> 1bde8342cac0f33f
> 0100000000000000

> linux arm:

> cac0f33f1bde8342
> 0100000000000000

> So, it indeed looks like 32bits based middle-endian or something

Right. So for your ARM FP library, the code goes from

    case 6:   /* 8-byte signed integer */
    case 7: { /* IEEE floating point */
      u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
      u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
      x = (x<<32) | y;
      if( serial_type==6 ){
        pMem->i = *(i64*)&x;
        pMem->flags = MEM_Int;
      }else{
        pMem->r = *(double*)&x;
        pMem->flags = MEM_Real;
      }

to

    case 6:   /* 8-byte signed integer */
      u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
      u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
      x = (x<<32) | y;
      pMem->i = *(i64*)&x;
      pMem->flags = MEM_Int;
      break;
    case 7: { /* IEEE floating point */
      u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
      u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
      x = (y<<32) | x;
      pMem->r = *(double*)&x;
      pMem->flags = MEM_Real;

e

Reply | Threaded
Open this post in threaded view
|

Re: Possible bug regarding endiannes and realstorageclass (sqlite3)

Frank van Vugt
> Right. So for your ARM FP library, the code goes from <cut>

Yep, will try that patch tomorrow morning, the soft-float cross-compiler
should be ready then as well, so we'll see if that makes any difference as
well.





--
Best,




Frank.
Reply | Threaded
Open this post in threaded view
|

Re: Possible bug regarding endiannes and realstorageclass (sqlite3)

D. Richard Hipp
On Thu, 2005-08-18 at 23:08 +0200, Frank van Vugt wrote:
> > Right. So for your ARM FP library, the code goes from <cut>
>
> Yep, will try that patch tomorrow morning, the soft-float cross-compiler
> should be ready then as well, so we'll see if that makes any difference as
> well.

The code shown was for reading the database.  You'll also need
to find and fix the spot where the database is written, of course.
--
D. Richard Hipp <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: Possible bug regarding endiannes and realstorageclass (sqlite3)

Frank van Vugt
> > > Right. So for your ARM FP library, the code goes from <cut>
> > Yep, will try that patch tomorrow morning

> The code shown was for reading the database.  You'll also need
> to find and fix the spot where the database is written, of course.

Obviously, but thanks for the heads-up anyway ;)

More on this in due time.




--
Best,




Frank.
Reply | Threaded
Open this post in threaded view
|

ODP: Possible bug regarding endiannes and realstorageclass (sqlite3)

Jarosław Nozderko
In reply to this post by Thomas Briggs
> Od: D. Richard Hipp [mailto:[hidden email]]
> Wysłano: 18 sierpnia 2005 20:11
> Do: [hidden email]
> Temat: Re: [sqlite] Possible bug regarding endiannes and
> realstorageclass (sqlite3)
>
> On Thu, 2005-08-18 at 09:40 -0700, Robert Simpson wrote:
> > http://www.psc.edu/general/software/packages/ieee/ieee.html
> >
> > The way I interpreted this site, is that the IEEE standard for
> > floating point numbers was processor agnostic and the
> storage of the
> > bits went from left to right.
> >
>
> I wrote a test program to print out the byte values for 1.0
> and 1 on both ix86 (Intel, Linux) and powerpc (G5, OS-X).  
> The results:
>
>     ix86:   000000000000f03f  0100000000000000
>  powerpc:   3ff0000000000000  0000000000000001
>
> This seems to validate the approach taken by SQLite, which is
> to byteswap floating point values on ix86 machines.

CORBA CDR specification also clearly states that floating
point numbers are byte swapped on different endian
architectures:

http://www.omg.org/docs/formal/04-03-01.pdf

15.3.1.3 "Floating Point Data Types"
Fig 15.2 on page 535

Regards,
Jarek
Reply | Threaded
Open this post in threaded view
|

Re: Possible bug regarding endiannes and realstorageclass (sqlite3)

Frank van Vugt
In reply to this post by Doug Currie-2
L.S.

In order to wrap this up: apparently there's a feature / bug (choose one) in
any ARM core earlier than v5 due to which a float will be stored in big
endian quad order. The processor in this particular case is an SA1110, which
is default little endian while having a v4 core..... (and thus is 'swapping'
the quads).

> [Doug Currie] So for your ARM FP library, the code goes from

For the part that reads the data it's just semantics, really, but I'm using
the patch now (against v3.2.3):

--- vdbeaux.c_orig      2005-08-22 21:32:53.000000000 +0200
+++ vdbeaux.c   2005-08-22 21:39:46.000000000 +0200
@@ -1649,7 +1649,11 @@
     }
     len = i = sqlite3VdbeSerialTypeLen(serial_type);
     while( i-- ){
-      buf[i] = (v&0xFF);
+      if( serial_type==7 ){
+        buf[(i+4)%8] = (v&0xFF);
+      }else{
+        buf[i] = (v&0xFF);
+      }
       v >>= 8;
     }
     return len;
@@ -1708,18 +1712,20 @@
       pMem->flags = MEM_Int;
       return 6;
     }
-    case 6:   /* 8-byte signed integer */
-    case 7: { /* IEEE floating point */
+    case 6: { /* 8-byte signed integer */
       u64 x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
       u32 y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
       x = (x<<32) | y;
-      if( serial_type==6 ){
-        pMem->i = *(i64*)&x;
-        pMem->flags = MEM_Int;
-      }else{
-        pMem->r = *(double*)&x;
-        pMem->flags = MEM_Real;
-      }
+      pMem->i = *(i64*)&x;
+      pMem->flags = MEM_Int;
+      return 8;
+    }
+    case 7: { /* IEEE floating point */
+      u64 x = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
+      u32 y = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+      x = (x<<32) | y;
+      pMem->r = *(double*)&x;
+      pMem->flags = MEM_Real;
       return 8;
     }
     default: {

>> [D. Richard Hipp] The code shown was for reading the database.
>> You'll also need to find and fix the spot where the database is written
> Obviously, but thanks for the heads-up anyway ;);)

The patch above includes that.



--
Best,




Frank.