Solved

Extended does not have 19-20 significant digits.

Posted on 2004-09-28
9
666 Views
Last Modified: 2008-02-01
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=========================

0
Comment
Question by:nmm
  • 4
  • 3
9 Comments
 
LVL 6

Expert Comment

by:gwalkeriq
Comment Utility
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.
 
0
 

Author Comment

by:nmm
Comment Utility
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.

0
 

Author Comment

by:nmm
Comment Utility
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
0
 
LVL 6

Expert Comment

by:gwalkeriq
Comment Utility
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.
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:nmm
Comment Utility
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

0
 

Author Comment

by:nmm
Comment Utility
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)
0
 
LVL 6

Expert Comment

by:gwalkeriq
Comment Utility
Sorry I was not able to help you, glad you got it figured out eventually.
0
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
Comment Utility
Question answered by asker or dialog valuable.
Closed, 500 points refunded.
ee_ai_construct (replacement part #xm34)
Community Support Admin
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now