Link to home
Start Free TrialLog in
Avatar of nmm
nmmFlag for Germany

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(TForm1, 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,fvExtended,20, 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,fvExtended,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=========================

Avatar of gwalkeriq
gwalkeriq

As far as I can see, this works perfectly fine with Delphi 6. I just ran your project and no digits lost (actually, I had to fix your project just a little, the Edit9: TEdit declaration is missing from your unit1.pas). I'm not aware of any compiler option that truncates extended to double precision digits (15.5 digits).

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.
 
Avatar of nmm

ASKER

Hi,

the result is 123456789.
But my Delphi6 shows in the edit-fields of the code-example above:

123451234512345114
123451234512345120,000000000000000000
123451234512345114
123451234512345120,000000000000000000
12345123451234512
123451234512345123
123451234512345114

What might be wrong?
I use Delphi 6 UP2 (Buld 6.240) on Win2000 SP4.

Avatar of nmm

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
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.
Avatar of nmm

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

Avatar of 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(pmExtended);

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
Avatar of ee_ai_construct
ee_ai_construct
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial