May be, that this can be fixed in sqldb.pp in function TSQLConnection.GetAsSQLText(Param: TParam) : string;
...
-    ftFloat    : Result := FloatToStr(Param.AsFloat, FSQLFormatSettings);
+ ftFloat : Result := FloatToStrF(extended(Param.AsFloat), ffGeneral, 16, 0, FSQLFormatSettings);
...
for me it seems, that works ... See atached program.
What do you think ?
-Laco.

On Mon, Jul 11, 2011 at 11:55 AM, Hans-Peter Diettrich
<[email protected]> wrote:

The binary value consists of an exponent and an significand (mantissa), most
probably you forgot to count the exponent and sign bits.

The problem I'm trying to describe is with double precision floating
point values.  When the query is open and one of the parameters is
double MySQL does not receive all of the memory.  It's missing two
bits.  That is a problem with either the mysql5.1 driver or with the
mysql51 component w/r/t the double data type.

I'd suggest that you read a bit about using floating point numbers. They
never are accurate, and every decimal representation adds more inaccuracy

I could understand if you wanted to bring this fact into argument over
arithmetic and cumulative error.  But the fact is - if I send a double
precision data value to a double precision field in the SQL database -
that value had better be the same - "bit for bit".  Now if someone is
being bit shifty on the conversion - that needs to be a addressed.
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel


program testDouble;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes,
  db, mysql51conn, sqldb,
  variants;


{$R *.res}

var
   Conn: TMySQL51Connection;
   Tran: TSQLTransaction;
   Q: TSQLQuery;
   d: double;

begin
  Conn:=TMySQL51Connection.Create(nil);
  Conn.HostName:='localhost';
  Conn.DatabaseName:='test';
  Conn.UserName:='root';
  Conn.Password:='root';

  Tran:=TSQLTransaction.Create(nil);
  Tran.DataBase:=Conn;

  Q:=TSQLQuery.Create(nil);
  Q.DataBase:=Conn;
  Q.Transaction:=Tran;

  Conn.Open;
  writeln('Connected');

  Conn.ExecuteDirect('CREATE TEMPORARY TABLE t (int_field INTEGER PRIMARY KEY, 
double_field double)');
  Conn.ExecuteDirect('INSERT INTO t VALUES(1, 40734.825668912039)');
  writeln('Table created');

  Q.SQL.Text:='select * from t';
  Q.Open;
  d:=40734.825668912039;
  Q.AppendRecord([2,d]);
  Q.ApplyUpdates;
  Q.Close;

  Q.SQL.Text:='select double_field, double_field-40734 from t';
  Q.Open;
  while not Q.Eof do begin
    writeln(Q.Fields[0].AsFloat:30:20, ':', Q.Fields[1].AsFloat:30:20);
    Q.Next;
  end;

  Tran.Commit;
  Conn.Close;

  Q.Free;
  Tran.Free;
  Conn.Free;

  writeln('End. Press any key');
  readln;
end.

_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to