Postgres 8.4 and Decimal
Moderators: gto, EgonHugeist
-
- Expert Boarder
- Posts: 164
- Joined: 18.03.2008, 13:03
- Contact:
It seems to be FPC bug.
http://forum.lazarus.freepascal.org/ind ... pic=8150.0
I've wrote a test procedure:
procedure TForm1.Button2Click(Sender: TObject);
var _real: Double;
_dc: char;
begin
_dc := DecimalSeparator;
DecimalSeparator:='.';
_real := StrToFloatDef('1.2', 0);
DecimalSeparator:= _dc;
end;
if your locale decimal separator is not '.' then the result of _real is 12 - not 1.2. I don't know if the zeos code should take into account the bugs from FPC...
http://forum.lazarus.freepascal.org/ind ... pic=8150.0
I've wrote a test procedure:
procedure TForm1.Button2Click(Sender: TObject);
var _real: Double;
_dc: char;
begin
_dc := DecimalSeparator;
DecimalSeparator:='.';
_real := StrToFloatDef('1.2', 0);
DecimalSeparator:= _dc;
end;
if your locale decimal separator is not '.' then the result of _real is 12 - not 1.2. I don't know if the zeos code should take into account the bugs from FPC...
- mdaems
- Zeos Project Manager
- Posts: 2766
- Joined: 20.09.2005, 15:28
- Location: Brussels, Belgium
- Contact:
Which is logical as they probably know their own limitations
Anyhow... I'd like to be sure to know what postgres returns in your cases. Is it effectively a ',' instead of '.'? In that case we don't have to talk about StrToFloatDef but about how we handle different decimal separators returned on different platforms.
To be honest, I think I had the same problem with mysql, but I just changed my settings so mysql returns decimal points... As zeoslib just assumes points are used. (By setting decimalseparator in the following function:
As said above : I think we need something to fix this assumption:
a) make sure it's true by provinding the right settings at connection time OR
b) check what settings are active on the specific connection and use that information when decoding numbers.
Last option seems best to me, but is more difficult to implement, I believe.
Anyhow... I'd like to be sure to know what postgres returns in your cases. Is it effectively a ',' instead of '.'? In that case we don't have to talk about StrToFloatDef but about how we handle different decimal separators returned on different platforms.
To be honest, I think I had the same problem with mysql, but I just changed my settings so mysql returns decimal points... As zeoslib just assumes points are used. (By setting decimalseparator in the following function:
Code: Select all
function SQLStrToFloatDef(Str: string; Def: Extended): Extended;
var
{$IFDEF DELPHI12_UP}
OldDecimalSeparator: WideChar;
{$ELSE}
OldDecimalSeparator: Char;
{$ENDIF}
begin
OldDecimalSeparator := DecimalSeparator;
DecimalSeparator := '.';
if Pos('$', Str) = 1 then
Str := Copy(Str, 2, Pred(Length(Str)));
If Str = '' then
Result := Def
else
Result := StrToFloatDef(Str, Def);
DecimalSeparator := OldDecimalSeparator;
end;
a) make sure it's true by provinding the right settings at connection time OR
b) check what settings are active on the specific connection and use that information when decoding numbers.
Last option seems best to me, but is more difficult to implement, I believe.
-
- Expert Boarder
- Posts: 164
- Joined: 18.03.2008, 13:03
- Contact:
I guess I've found the problem - its thousand separator. On locale settings I have it set to ".". FPC eliminates all thousand separator characters before trying to get float from string. As my thousand is set to "." FPC eliminates all "." characters in Str and so Decimal separator is lost too. My guess is that Delphi treats Str differently. I tried looking into SysUtils.TextToFloat, but I'm not so good at asm.
Do you have "." as thousand separator, baba?
Do you have "." as thousand separator, baba?
-
- Expert Boarder
- Posts: 164
- Joined: 18.03.2008, 13:03
- Contact:
- mdaems
- Zeos Project Manager
- Posts: 2766
- Joined: 20.09.2005, 15:28
- Location: Brussels, Belgium
- Contact:
Wild_Pointer,
That makes it a fpc specific problem, but it's not unreasonable. If zeoslib sets thousands=decimals in the coding, it's our own stupid fault, isn't it?
In my fpc version (2.5.1) and version 2.3.1 this seems fixed, in 2.2.2 it wasn't yet. Don't know about 2.2.4.
I guess we could solve this by overriding the thousand separator as well when using fpc, effectively forcing thousands := ',' and decimals:='.' in the code above? Even Delphi 5 support this, apparently.
Can you give this code a try?
Mark
That makes it a fpc specific problem, but it's not unreasonable. If zeoslib sets thousands=decimals in the coding, it's our own stupid fault, isn't it?
In my fpc version (2.5.1) and version 2.3.1 this seems fixed, in 2.2.2 it wasn't yet. Don't know about 2.2.4.
I guess we could solve this by overriding the thousand separator as well when using fpc, effectively forcing thousands := ',' and decimals:='.' in the code above? Even Delphi 5 support this, apparently.
Can you give this code a try?
Code: Select all
function SQLStrToFloatDef(Str: string; Def: Extended): Extended;
var
{$IFDEF DELPHI12_UP}
OldDecimalSeparator: WideChar;
OldThousandSeparator: WideChar;
{$ELSE}
OldDecimalSeparator: Char;
OldThousandSeparator: Char;
{$ENDIF}
begin
OldDecimalSeparator := DecimalSeparator;
OldThousandSeparator := ThousandSeparator;
DecimalSeparator := '.';
ThousandSeparator := ',';
if Pos('$', Str) = 1 then
Str := Copy(Str, 2, Pred(Length(Str)));
If Str = '' then
Result := Def
else
Result := StrToFloatDef(Str, Def);
DecimalSeparator := OldDecimalSeparator;
ThousandSeparator := OldThousandSeparator;
end;
- mdaems
- Zeos Project Manager
- Posts: 2766
- Joined: 20.09.2005, 15:28
- Location: Brussels, Belgium
- Contact:
Just made a small demo console program that confirms the conclusion above. I'll attach it to this post.
Compiled it using fpc 2.2.2 and both strtofloatdef and old (zeos) SQLStrToFloatDef give bad results, depending on the decimal and thousand separator settings. New (zeos) SQLStrToFloatDef works like expected.
Compiled it using fpc 2.5.1 and all 3 functions work like expected.
So I did commit the change to testing branch. (SVN rev. 761)
Does somebody think we should ifdef the changes so we only do them when using FPC versions below 2.3?
Mark
Compiled it using fpc 2.2.2 and both strtofloatdef and old (zeos) SQLStrToFloatDef give bad results, depending on the decimal and thousand separator settings. New (zeos) SQLStrToFloatDef works like expected.
Compiled it using fpc 2.5.1 and all 3 functions work like expected.
So I did commit the change to testing branch. (SVN rev. 761)
Does somebody think we should ifdef the changes so we only do them when using FPC versions below 2.3?
Mark
You do not have the required permissions to view the files attached to this post.
-
- Expert Boarder
- Posts: 164
- Joined: 18.03.2008, 13:03
- Contact:
-
- Expert Boarder
- Posts: 164
- Joined: 18.03.2008, 13:03
- Contact:
Your test program works ok on my computer:
StrToFloatDef('12.5')=
Using locale (thousands=. decimals=,): 125,00
Using thousands=, decimals=.: 12.50
Using thousands=. decimals=.: 125.00
Using thousands=. decimals=,: 125,00
OldSQLStrToFloatDef('12.5')=
Using locale (thousands=. decimals=,): 125,00
Using thousands=, decimals=.: 12.50
Using thousands=. decimals=.: 125.00
Using thousands=. decimals=,: 125,00
SQLStrToFloatDef('12.5')=
Using locale (thousands=. decimals=,): 12,50
Using thousands=, decimals=.: 12.50
Using thousands=. decimals=.: 12.50
Using thousands=. decimals=,: 12,50
Also I changed the function SQLStrToFloatDef to the one you provided and it works OK. Thank you.
As baba is the one who opened the issue, I think it's he who should confirm the resolution.
StrToFloatDef('12.5')=
Using locale (thousands=. decimals=,): 125,00
Using thousands=, decimals=.: 12.50
Using thousands=. decimals=.: 125.00
Using thousands=. decimals=,: 125,00
OldSQLStrToFloatDef('12.5')=
Using locale (thousands=. decimals=,): 125,00
Using thousands=, decimals=.: 12.50
Using thousands=. decimals=.: 125.00
Using thousands=. decimals=,: 125,00
SQLStrToFloatDef('12.5')=
Using locale (thousands=. decimals=,): 12,50
Using thousands=, decimals=.: 12.50
Using thousands=. decimals=.: 12.50
Using thousands=. decimals=,: 12,50
Also I changed the function SQLStrToFloatDef to the one you provided and it works OK. Thank you.
As baba is the one who opened the issue, I think it's he who should confirm the resolution.
-
- Expert Boarder
- Posts: 164
- Joined: 18.03.2008, 13:03
- Contact: