nmm
asked on
Extended does not have 19-20 significant digits.
Hi,
if you load a extended vatiable with an integer of 18 digits to than the extended variable has wrong content.
The strange thing is, that this was in Delphi1 no problm! But in Delphi6.
Any hint?
Regards
nmm
program i64ext;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TFo rm1, Form1);
Application.Run;
end.
UNIT1.PAS:================ =====
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;
type
TForm1 = class(TForm)
Edit1: TEdit;
BitBtn1: TBitBtn;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit5: TEdit;
Edit6: TEdit;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Edit7: TEdit;
Label7: TLabel;
Edit8: TEdit;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
procedure BitBtn1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.BitBtn1Click(Sender : TObject);
var e,f,g:extended;ok:integer;
i64:int64;
s:string;
DecVal: TFloatRec;
begin
val(edit1.Text,e,ok);
f:=StrToFloat(edit1.Text);
edit3.Text:=inttostr(ok);
str(e:18:0,s);
edit2.Text:=s;
val(edit1.Text,i64,ok);
edit8.Text:=inttostr(i64);
edit4.Text:=FloatToStrF(e, ffFixed,20 ,18);
str(f:18:0,s);
edit5.Text:=s;
edit6.Text:=FloatToStrF(f, ffFixed,20 ,18);
FloatToDecimal(DecVal,e,fv Extended,2 0, 20);
edit7.Text:=decval.Digits;
g:=123451234512345123;
str(g:18:0,s);
edit9.Text:=s;
end;
end.
UNIT1.PAS================= =====
UNIT1.DFM================= ========
object Form1: TForm1
Left = 229
Top = 103
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 96
Top = 200
Width = 134
Height = 13
Caption = 'FloatToStrF(e,ffFixed,20, 18);'
end
object Label2: TLabel
Left = 176
Top = 176
Width = 55
Height = 13
Caption = 'str(e:18:0,s)'
end
object Label3: TLabel
Left = 256
Top = 128
Width = 174
Height = 13
Caption = 'e ergibt sich aus: val(edit1.Text,e,ok)'
end
object Label4: TLabel
Left = 256
Top = 144
Width = 117
Height = 13
Caption = ' f:=StrToFloat(edit1.Text)'
end
object Label5: TLabel
Left = 176
Top = 240
Width = 52
Height = 13
Caption = 'str(f:18:0,s)'
end
object Label6: TLabel
Left = 104
Top = 264
Width = 128
Height = 13
Caption = 'FloatToStrF(f,ffFixed,20, 18)'
end
object Label7: TLabel
Left = 8
Top = 304
Width = 214
Height = 13
Caption = 'FloatToDecimal(DecVal,e,f vExtended, 20, 20)'
end
object Label8: TLabel
Left = 120
Top = 336
Width = 102
Height = 13
Caption = ' val(edit1.Text,i64,ok)'
end
object Label9: TLabel
Left = 40
Top = 24
Width = 59
Height = 13
Caption = 'e,f:extended'
end
object Label10: TLabel
Left = 40
Top = 40
Width = 40
Height = 13
Caption = 'i64:int64'
end
object Label11: TLabel
Left = 8
Top = 368
Width = 187
Height = 13
Caption = ' g:=123451234512345123; str(g:18:0,s)'
end
object Edit1: TEdit
Left = 168
Top = 88
Width = 225
Height = 21
TabOrder = 0
Text = '123451234512345123'
end
object BitBtn1: TBitBtn
Left = 432
Top = 88
Width = 75
Height = 25
Caption = 'BitBtn1'
TabOrder = 1
OnClick = BitBtn1Click
end
object Edit2: TEdit
Left = 240
Top = 176
Width = 225
Height = 21
TabOrder = 2
end
object Edit3: TEdit
Left = 168
Top = 128
Width = 49
Height = 21
TabOrder = 3
end
object Edit4: TEdit
Left = 240
Top = 200
Width = 225
Height = 21
TabOrder = 4
end
object Edit5: TEdit
Left = 240
Top = 240
Width = 225
Height = 21
TabOrder = 5
end
object Edit6: TEdit
Left = 240
Top = 264
Width = 225
Height = 21
TabOrder = 6
end
object Edit7: TEdit
Left = 240
Top = 304
Width = 225
Height = 21
TabOrder = 7
end
object Edit8: TEdit
Left = 240
Top = 336
Width = 225
Height = 21
TabOrder = 8
end
object Edit9: TEdit
Left = 240
Top = 368
Width = 225
Height = 21
TabOrder = 9
end
end
UNIT1.DFM================= ========
if you load a extended vatiable with an integer of 18 digits to than the extended variable has wrong content.
The strange thing is, that this was in Delphi1 no problm! But in Delphi6.
Any hint?
Regards
nmm
program i64ext;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TFo
Application.Run;
end.
UNIT1.PAS:================
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;
type
TForm1 = class(TForm)
Edit1: TEdit;
BitBtn1: TBitBtn;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit5: TEdit;
Edit6: TEdit;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Edit7: TEdit;
Label7: TLabel;
Edit8: TEdit;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
procedure BitBtn1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.BitBtn1Click(Sender
var e,f,g:extended;ok:integer;
i64:int64;
s:string;
DecVal: TFloatRec;
begin
val(edit1.Text,e,ok);
f:=StrToFloat(edit1.Text);
edit3.Text:=inttostr(ok);
str(e:18:0,s);
edit2.Text:=s;
val(edit1.Text,i64,ok);
edit8.Text:=inttostr(i64);
edit4.Text:=FloatToStrF(e,
str(f:18:0,s);
edit5.Text:=s;
edit6.Text:=FloatToStrF(f,
FloatToDecimal(DecVal,e,fv
edit7.Text:=decval.Digits;
g:=123451234512345123;
str(g:18:0,s);
edit9.Text:=s;
end;
end.
UNIT1.PAS=================
UNIT1.DFM=================
object Form1: TForm1
Left = 229
Top = 103
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 96
Top = 200
Width = 134
Height = 13
Caption = 'FloatToStrF(e,ffFixed,20,
end
object Label2: TLabel
Left = 176
Top = 176
Width = 55
Height = 13
Caption = 'str(e:18:0,s)'
end
object Label3: TLabel
Left = 256
Top = 128
Width = 174
Height = 13
Caption = 'e ergibt sich aus: val(edit1.Text,e,ok)'
end
object Label4: TLabel
Left = 256
Top = 144
Width = 117
Height = 13
Caption = ' f:=StrToFloat(edit1.Text)'
end
object Label5: TLabel
Left = 176
Top = 240
Width = 52
Height = 13
Caption = 'str(f:18:0,s)'
end
object Label6: TLabel
Left = 104
Top = 264
Width = 128
Height = 13
Caption = 'FloatToStrF(f,ffFixed,20,
end
object Label7: TLabel
Left = 8
Top = 304
Width = 214
Height = 13
Caption = 'FloatToDecimal(DecVal,e,f
end
object Label8: TLabel
Left = 120
Top = 336
Width = 102
Height = 13
Caption = ' val(edit1.Text,i64,ok)'
end
object Label9: TLabel
Left = 40
Top = 24
Width = 59
Height = 13
Caption = 'e,f:extended'
end
object Label10: TLabel
Left = 40
Top = 40
Width = 40
Height = 13
Caption = 'i64:int64'
end
object Label11: TLabel
Left = 8
Top = 368
Width = 187
Height = 13
Caption = ' g:=123451234512345123; str(g:18:0,s)'
end
object Edit1: TEdit
Left = 168
Top = 88
Width = 225
Height = 21
TabOrder = 0
Text = '123451234512345123'
end
object BitBtn1: TBitBtn
Left = 432
Top = 88
Width = 75
Height = 25
Caption = 'BitBtn1'
TabOrder = 1
OnClick = BitBtn1Click
end
object Edit2: TEdit
Left = 240
Top = 176
Width = 225
Height = 21
TabOrder = 2
end
object Edit3: TEdit
Left = 168
Top = 128
Width = 49
Height = 21
TabOrder = 3
end
object Edit4: TEdit
Left = 240
Top = 200
Width = 225
Height = 21
TabOrder = 4
end
object Edit5: TEdit
Left = 240
Top = 240
Width = 225
Height = 21
TabOrder = 5
end
object Edit6: TEdit
Left = 240
Top = 264
Width = 225
Height = 21
TabOrder = 6
end
object Edit7: TEdit
Left = 240
Top = 304
Width = 225
Height = 21
TabOrder = 7
end
object Edit8: TEdit
Left = 240
Top = 336
Width = 225
Height = 21
TabOrder = 8
end
object Edit9: TEdit
Left = 240
Top = 368
Width = 225
Height = 21
TabOrder = 9
end
end
UNIT1.DFM=================
ASKER
Hi,
the result is 123456789.
But my Delphi6 shows in the edit-fields of the code-example above:
123451234512345114
123451234512345120,0000000 0000000000 0
123451234512345114
123451234512345120,0000000 0000000000 0
12345123451234512
123451234512345123
123451234512345114
What might be wrong?
I use Delphi 6 UP2 (Buld 6.240) on Win2000 SP4.
the result is 123456789.
But my Delphi6 shows in the edit-fields of the code-example above:
123451234512345114
123451234512345120,0000000
123451234512345114
123451234512345120,0000000
12345123451234512
123451234512345123
123451234512345114
What might be wrong?
I use Delphi 6 UP2 (Buld 6.240) on Win2000 SP4.
ASKER
I tried the EXE-file from the code above on different computers (without Delphi installed).
It seems, that the strange calculation error depend on somthing different in the system/systemconfiguration .
The tested computers where
Win2000 Server SP4 --> wrong calculation
Win2000 Pro SP4 --> wrong calculation
other Win2000 Server SP4 --> calculation OK
Win XP SP1 ->calculation OK
unfortunately I can up to now not see, what the difference on the "good" and "bad" computers are.
May be the problm is not a Delphi-matter. It depends on the system (for I used the same EXE on all tested computers).
Have you any idea, what the cause of this can be?
Reagrds
nmm
It seems, that the strange calculation error depend on somthing different in the system/systemconfiguration
The tested computers where
Win2000 Server SP4 --> wrong calculation
Win2000 Pro SP4 --> wrong calculation
other Win2000 Server SP4 --> calculation OK
Win XP SP1 ->calculation OK
unfortunately I can up to now not see, what the difference on the "good" and "bad" computers are.
May be the problm is not a Delphi-matter. It depends on the system (for I used the same EXE on all tested computers).
Have you any idea, what the cause of this can be?
Reagrds
nmm
OK. Since the answer is 123456789 (presumably on one of the computers where you see wrong answers on the form), the extended math is compiling correctly. The issue is presumably related to formatting of the output strings.
If you have the desire / expertise, compile with optimization off and use debug dcu's. You should then be ablt to track into the formatting code hopefully on a system where it works, and one where it does not. This should make the difference stand out.
If you link with Debug DCU's, you can trace into the formatting code, and maybe resolve the difference.
If that fails, I would recommend contacting Borland for support, loath as I am to suggest such normally.
If you have the desire / expertise, compile with optimization off and use debug dcu's. You should then be ablt to track into the formatting code hopefully on a system where it works, and one where it does not. This should make the difference stand out.
If you link with Debug DCU's, you can trace into the formatting code, and maybe resolve the difference.
If that fails, I would recommend contacting Borland for support, loath as I am to suggest such normally.
ASKER
Hi again, I have now an reproducable hint:
IF i64ext.exe loads MSVCRT.DLL THAN the programm shows the wrong numbers.
IF MSVCRT.DLL ist not loaded, than the values are OK.
Now i64ext.exe obviously dont load msvcrt.dll explicit, but there are programs, that can force i64ext.exe to load it.
Example: on the computer I usually use there are a is Soundbaster Live Soundcard. The drivers from this card starts a programm CTHELPER.EXE. If this programm is running, than i64ext.exe loads msvcrt.dll.
There are serveral other programms, that can force to load the dll: on a different computer (without Soundblaster-Card!!), I tried winvnc-server. If the server is connected, than a special DLL VNCHooks.dll is loades by every programm, but this DLL seemingly is loading msvcrt.dll, so i64ext.exe loads it and turns to the stange behavior.
If I cancel the VNC-connection and restart i64ext.exe than ist shows again the corrct values.
An idea?
(The msvcrt.dll has on both tested computers version 6.01.9844.0000, both computers run Win2000Pro SP4.)
regards
nmm
IF i64ext.exe loads MSVCRT.DLL THAN the programm shows the wrong numbers.
IF MSVCRT.DLL ist not loaded, than the values are OK.
Now i64ext.exe obviously dont load msvcrt.dll explicit, but there are programs, that can force i64ext.exe to load it.
Example: on the computer I usually use there are a is Soundbaster Live Soundcard. The drivers from this card starts a programm CTHELPER.EXE. If this programm is running, than i64ext.exe loads msvcrt.dll.
There are serveral other programms, that can force to load the dll: on a different computer (without Soundblaster-Card!!), I tried winvnc-server. If the server is connected, than a special DLL VNCHooks.dll is loades by every programm, but this DLL seemingly is loading msvcrt.dll, so i64ext.exe loads it and turns to the stange behavior.
If I cancel the VNC-connection and restart i64ext.exe than ist shows again the corrct values.
An idea?
(The msvcrt.dll has on both tested computers version 6.01.9844.0000, both computers run Win2000Pro SP4.)
regards
nmm
ASKER
Here is the solution: msvcrt.dll in dead sets on loading the FPU in the 64-Bit precision mode by default.
This is IMHO a bug.
One can reset to 80-Bit mode using
SetPrecisionMode(pmExtende d);
from unit math.
Under XP msvcrt.dll will not change the FPU-mode.
regards
nmm
(a hint I found was:
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q308702)
This is IMHO a bug.
One can reset to 80-Bit mode using
SetPrecisionMode(pmExtende
from unit math.
Under XP msvcrt.dll will not change the FPU-mode.
regards
nmm
(a hint I found was:
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q308702)
Sorry I was not able to help you, glad you got it figured out eventually.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Just twosuggestion, if you have an old Pentium, check the Pentiium Safe FDIV project compiler option.
I am also using the patched version of the Delphi6 run-time libraries. Make sure you have those (not that I'm aware of a patch here either).
Since FPU built into pentium's, its hard to guess where this would be a bug in Borland code.
Finally, try this simple code:
var
e, f: extended;
e := 123456789123456789;
f := e - 123456789000000000;
// f should now be 123456789;
If f is not 123456789, let me know what it is instead.