Solved

Extended does not have 19-20 significant digits.

Posted on 2004-09-28
9
696 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
9 Comments
 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12175247
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
ID: 12177470
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
ID: 12178030
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:gwalkeriq
ID: 12181160
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
 

Author Comment

by:nmm
ID: 12200606
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
ID: 12205375
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
ID: 12217688
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
ID: 12259753
Question answered by asker or dialog valuable.
Closed, 500 points refunded.
ee_ai_construct (replacement part #xm34)
Community Support Admin
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

719 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