Hello,
I don't know if it's really a bug but the result is really surprising. A LongReal variable (of simple integer value) is written into a text file, and when I read this value back : it isn't exactly the same.
In the following program, the problem disappears : - if Var A,B : LongReal; is replaced by Var A,B : Real;
- or if Writeln(TextFile,A); is replaced by Writeln(TextFile,A:0:18);
- or if Readln(TextFile,B); is replaced by Readln(TextFile,B); B := Real(B);
I would like to understand this strange behaviour.
---------------------------------------------------------------------------- -- Program LRealBug; Var A,B : LongReal; TextFile : Text; Begin Assign(TextFile,'tmp'); Rewrite(TextFile); A := 103; Writeln(TextFile,A); Close(TextFile); Reset(TextFile); Readln(TextFile,B); Close(TextFile); Erase (TextFile); If A <> B Then Writeln('Failed') Else Writeln('OK'); End. ---------------------------------------------------------------------------- --
I have : gpc version 20000727, based on 2.95.2 19991024 (release)
-- «Couperin»
On Sat, 24 Mar 2001, f.couperin wrote:
Hello,
I don't know if it's really a bug but the result is really surprising. A LongReal variable (of simple integer value) is written into a text file, and when I read this value back : it isn't exactly the same.
[..]
Program LRealBug; Var A,B : LongReal; TextFile : Text; Begin Assign(TextFile,'tmp'); Rewrite(TextFile); A := 103; Writeln(TextFile,A); Close(TextFile); Reset(TextFile); Readln(TextFile,B); Close(TextFile); Erase (TextFile); If A <> B Then Writeln('Failed') Else Writeln('OK'); End.
The problem is "A <> B": adding two lines to program writeln('A= ', A); writeln('B= ', B); and I got:
A= 1.030000000000000e+02 B= 1.030000000000000e+02 Failed
Hopes this helps Russ
Russ Whitaker russ@ashlandhome.net wrote :
The problem is "A <> B": adding two lines to program writeln('A= ', A); writeln('B= ', B); and I got:
A= 1.030000000000000e+02 B= 1.030000000000000e+02 Failed
You'll see the difference with : Writeln('A = ',A:32); Writeln('B = ',B:32); or with Writeln('A - B = ',A-B);
Hope it helps.
-- «Couperin»
On Sat, 24 Mar 2001, f.couperin wrote:
Russ Whitaker russ@ashlandhome.net wrote :
The problem is "A <> B": adding two lines to program writeln('A= ', A); writeln('B= ', B); and I got:
A= 1.030000000000000e+02 B= 1.030000000000000e+02 Failed
You'll see the difference with : Writeln('A = ',A:32); Writeln('B = ',B:32); or with Writeln('A - B = ',A-B);
You can also get "OK" in the original program by inserting the line B := round(B);
It all gets back to representing non-integers in binary format. Some non-integers require an infinate number of bits to get an *exact* representation.
For example, 1.3 is equivalent to the series 1 + 1/4 + 1/32 + ... or 1.01001 ...
Russ
On Sat, 24 Mar 2001, Russ Whitaker wrote:
On Sat, 24 Mar 2001, f.couperin wrote:
Hello,
I don't know if it's really a bug but the result is really surprising. A LongReal variable (of simple integer value) is written into a text file, and when I read this value back : it isn't exactly the same.
[..]
Program LRealBug; Var A,B : LongReal; TextFile : Text; Begin Assign(TextFile,'tmp'); Rewrite(TextFile); A := 103; Writeln(TextFile,A); Close(TextFile); Reset(TextFile); Readln(TextFile,B); Close(TextFile); Erase (TextFile); If A <> B Then Writeln('Failed') Else Writeln('OK'); End.
The problem is "A <> B": adding two lines to program writeln('A= ', A); writeln('B= ', B); and I got:
A= 1.030000000000000e+02 B= 1.030000000000000e+02 Failed
Hopes this helps Russ
Why should this help? If A=B the answer should be 'OK'. But there may be the long time known problem with comparing real numbers nearly zero difference, equality comparison of real's is never reliable.
Ernst-Ludwig
A= 1.030000000000000e+02 B= 1.030000000000000e+02 Failed
Hopes this helps Russ
Why should this help? If A=B the answer should be 'OK'. But there may be the long time known problem with comparing real numbers nearly zero difference, equality comparison of real's is never reliable.
Ernst-Ludwig
After thinking 3 more minutes about this problem, the conversion between binary and decimal presentation may produce low order bit differences of A and B ;-)). Other types (real etc) may veil the latent problem.
Ernst-Ludwig
Ernst-Ludwig Bohnen wrote:
On Sat, 24 Mar 2001, Russ Whitaker wrote:
On Sat, 24 Mar 2001, f.couperin wrote:
Hello,
I don't know if it's really a bug but the result is really surprising. A LongReal variable (of simple integer value) is written into a text file, and when I read this value back : it isn't exactly the same.
[..]
Program LRealBug; Var A,B : LongReal; TextFile : Text; Begin Assign(TextFile,'tmp'); Rewrite(TextFile); A := 103; Writeln(TextFile,A); Close(TextFile); Reset(TextFile); Readln(TextFile,B); Close(TextFile); Erase (TextFile); If A <> B Then Writeln('Failed') Else Writeln('OK'); End.
The problem is "A <> B": adding two lines to program writeln('A= ', A); writeln('B= ', B); and I got:
A= 1.030000000000000e+02 B= 1.030000000000000e+02 Failed
Hopes this helps Russ
Why should this help? If A=B the answer should be 'OK'. But there may be the long time known problem with comparing real numbers nearly zero difference, equality comparison of real's is never reliable.
[...]
After thinking 3 more minutes about this problem, the conversion between binary and decimal presentation may produce low order bit differences of A and B ;-)). Other types (real etc) may veil the latent problem.
Exactly. If you add the statements:
WriteLn (A - 103); WriteLn (B - 103);
you'll see:
0.000000000000000e+00 -6.938893903907228e-18
So, why is B slighly inaccurate? Well, if you look at the file, it contains the text:
1.030000000000000e+02
And that's exactly what ReadLn sees. I.e., first the number 1.03 which cannot be represented exactly since floating point numbers (at least IEEE and most other popular formats) are binary, not decimal, and 1.03 in binary is periodic.
Afterwards, it finds `e+02' and multiplies the result by 100 which can be done exactly, but the error was already made.
So, why does it happen only with LongReal?
Normally, a floating point system uses a few extra digits to avoid such roundoff errors. But (at least on Intel compatibles), this only holds for the regular types (ShortReal aka Single and Real aka Double). LongReal (aka Extended), however, is the full precision used internally, so there are no extra digits, and every roundoff error really shows. I think it was originally meant as an internal type, only to be used to store intermediate results, and not as a type to be used at the "user level". So if you do that, you're basically on your own. (I don't know if there are processors that provide a LongReal type bigger than Double which does have some extra digits internally.)
BTW, if you do
WriteLn (TextFile, A:0:30);
or something like that, A will be written as 103.000000000000000000000000000000, and B will be read back precisely, but that's no general help against roundoff errors...
Frank
Frank Heckenbach wrote :
[...]
So, why is B slighly inaccurate? Well, if you look at the file, it contains the text:
1.030000000000000e+02
And that's exactly what ReadLn sees. I.e., first the number 1.03 which cannot be represented exactly since floating point numbers (at least IEEE and most other popular formats) are binary, not decimal, and 1.03 in binary is periodic.
Afterwards, it finds `e+02' and multiplies the result by 100 which can be done exactly, but the error was already made.
[...]
Is this really computer dependent or does it depend of the program ? I think that reading 1.030000000000000e+02 as 1030000000000000 * 10^(-15+2) would suppress the problem. Wouldn't it be better ?
What I don't understand is that there is no problem if Readln reads 10.3e+01 in the file (10.3 isn't periodic in binary). And if it reads 103000e-03 (103000 IS periodic), the value is slightly wrong... (I tested this strange behaviour with the program shown below.)
I'm wondering if there's a way to write a binary (or hexadecimal) representation of the LongReal type in a text file, a clear and understandable representation that could be read back by the program without any difference with the original number. I wrote LongReal numbers to a File Of LongReal, and I translated this file into an hexadecimal representation, but the result was really unclear to me and I didn't understand the logic behind those numbers. I found and read this web page : http://www.infobiogen.fr/docs/info/SUNWspro/pascal/lang_ref/ref_data.doc.htm l (about another Pascal compiler) but it seems the GPC LongReal type is different from what is described there.
Program Bug09; Var A,B,C,D,E,F,G,H,I : LongReal; TextFile : Text; Begin Assign(TextFile,'tmp'); Rewrite(TextFile); Writeln(TextFile,'1030000e-04'); Writeln(TextFile,'103000e-03'); Writeln(TextFile,'10300e-02'); Writeln(TextFile,'1030e-01'); Writeln(TextFile,'103'); Writeln(TextFile,'10.3e+01'); Writeln(TextFile,'1.03e+02'); Writeln(TextFile,'0.103e+03'); Writeln(TextFile,'0.0103e+04'); Close(TextFile); Reset(TextFile); Readln(TextFile,A); Readln(TextFile,B); Readln(TextFile,C); Readln(TextFile,D); Readln(TextFile,E); Readln(TextFile,F); Readln(TextFile,G); Readln(TextFile,H); Readln(TextFile,I); Close(TextFile); Erase (TextFile); Writeln; Writeln('A = ',A:28); {Inaccurate} Writeln('B = ',B:28); {Inaccurate} Writeln('C = ',C:28); {OK} Writeln('D = ',D:28); {OK} Writeln('E = ',E:28); {OK} Writeln('F = ',F:28); {OK} Writeln('G = ',G:28); {Inaccurate} Writeln('H = ',H:28); {Inaccurate} Writeln('I = ',I:28); {Inaccurate} End.
-- «Couperin»
Hallo,
in order to put some light on the problem, I modified your program (appended below). It prints in addition the bit pattern of A and B, and allows to modify the type of values (recompile).
It seems to me that there is really a problem with the LongReal type. I don't know how many bits/bytes this type is using, may be more than 64 bits which is the test programs maximum limit. ShortReal (bits=32) and Real (bits=64) work nearly correct, with sometimes different low order bits, due to rounding effects. Here some results, A - B pairs of type Real (64 bits):
1.030000000000000e+02 0100000001011001110000000000000000000000000000000000000000000000 1.030000000000000e+02 0100000001011001110000000000000000000000000000000000000000000000 OK
1.300000000000000e+00 0011111111110100110011001100110011001100110011001100110011001101 1.300000000000000e+00 0011111111110100110011001100110011001100110011001100110011001101 OK
3.333333333333333e-01 0011111111010101010101010101010101010101010101010101010101010101 3.333333333333333e-01 0011111111010101010101010101010101010101010101010101010101010101 OK
Ernst-Ludwig
On Sun, 25 Mar 2001, f.couperin wrote: OK
Frank Heckenbach wrote :
[...]
So, why is B slighly inaccurate? Well, if you look at the file, it contains the text:
1.030000000000000e+02
And that's exactly what ReadLn sees. I.e., first the number 1.03 which cannot be represented exactly since floating point numbers (at least IEEE and most other popular formats) are binary, not decimal, and 1.03 in binary is periodic.
Afterwards, it finds `e+02' and multiplies the result by 100 which can be done exactly, but the error was already made.
[...]
Is this really computer dependent or does it depend of the program ? I think that reading 1.030000000000000e+02 as 1030000000000000 * 10^(-15+2) would suppress the problem. Wouldn't it be better ?
What I don't understand is that there is no problem if Readln reads 10.3e+01 in the file (10.3 isn't periodic in binary). And if it reads 103000e-03 (103000 IS periodic), the value is slightly wrong... (I tested this strange behaviour with the program shown below.)
I'm wondering if there's a way to write a binary (or hexadecimal) representation of the LongReal type in a text file, a clear and understandable representation that could be read back by the program without any difference with the original number. I wrote LongReal numbers to a File Of LongReal, and I translated this file into an hexadecimal representation, but the result was really unclear to me and I didn't understand the logic behind those numbers. I found and read this web page : http://www.infobiogen.fr/docs/info/SUNWspro/pascal/lang_ref/ref_data.doc.htm l (about another Pascal compiler) but it seems the GPC LongReal type is different from what is described there.
Program Bug09; Var A,B,C,D,E,F,G,H,I : LongReal; TextFile : Text; Begin Assign(TextFile,'tmp'); Rewrite(TextFile); Writeln(TextFile,'1030000e-04'); Writeln(TextFile,'103000e-03'); Writeln(TextFile,'10300e-02'); Writeln(TextFile,'1030e-01'); Writeln(TextFile,'103'); Writeln(TextFile,'10.3e+01'); Writeln(TextFile,'1.03e+02'); Writeln(TextFile,'0.103e+03'); Writeln(TextFile,'0.0103e+04'); Close(TextFile); Reset(TextFile); Readln(TextFile,A); Readln(TextFile,B); Readln(TextFile,C); Readln(TextFile,D); Readln(TextFile,E); Readln(TextFile,F); Readln(TextFile,G); Readln(TextFile,H); Readln(TextFile,I); Close(TextFile); Erase (TextFile); Writeln; Writeln('A = ',A:28); {Inaccurate} Writeln('B = ',B:28); {Inaccurate} Writeln('C = ',C:28); {OK} Writeln('D = ',D:28); {OK} Writeln('E = ',E:28); {OK} Writeln('F = ',F:28); {OK} Writeln('G = ',G:28); {Inaccurate} Writeln('H = ',H:28); {Inaccurate} Writeln('I = ',I:28); {Inaccurate} End.
-- «Couperin»
Program LRealBug; {-*-Mode: fundamental-mode} { variations of bits & real_type} const { OK OK Failed!!} bits = 64; { bits= 32 bits= 64 bits= 64} type real_type = Real; { ShortReal Real LongReal} word_type = word (bits); bit_str = string (bits); T= record case integer of 0: (A, B: real_type); { contains the real value } 1: (I, J: word_type); { contains the real value as bit pattern } end; Var V : T; TextFile : Text;
function bits2str (value: word_type): bit_str; {converts a word into string (binary)} var w, m: word_type; i: integer; s: bit_str; begin w:= value; s:=''; m:= 1 shl (bits-2); m:= m shl 1; {sorry, GPC thinks m to be a signed integer} for i:= 1 to bits do {1 shl (bits-1) is an error at compile time} begin if (w and m) = 0 then s:= s + '0' else s:= s + '1'; w:= w shl 1 end; bits2str:= s end;
procedure try (value: real_type); Begin with V do begin A:= value; Assign(TextFile,'tmp'); Rewrite(TextFile); Writeln(TextFile, A); Close(TextFile); Reset(TextFile); Readln(TextFile,B); Close(TextFile); Erase (TextFile); writeln (A, ' ', bits2str (I)); writeln (B, ' ', bits2str (J)); If A <> B Then Writeln('Failed') Else Writeln('OK'); end End;
Begin try (103.0); try (10300e-02); try (1.3); try (1.0/3.0); try (1.0/3.1111); try (7.0/3.0) end.
Hi
Ernst-Ludwig Bohnen wrote:
Hallo,
It seems to me that there is really a problem with the LongReal type. I don't know how many bits/bytes this type is using, may be more than 64 bits which is the test programs maximum limit.
If longReal corresponds to 'extended' on x86, then it is represented by 10 bytes (80 bits). This held since the days of i80387 as I remember.
George
least IEEE and most other popular formats) are binary, not decimal, and 1.03 in binary is periodic.
Afterwards, it finds `e+02' and multiplies the result by 100 which can be done exactly, but the error was already made.
[...]
Is this really computer dependent or does it depend of the program ?
Floating point behaviour is dpendant on a lot of things: - Processor (and its configuration, status word etc). - RTL routines. - User routines.
What I don't understand is that there is no problem if Readln reads 10.3e+01 in the file (10.3 isn't periodic in binary). And if it reads 103000e-03 (103000 IS periodic), the value is slightly wrong... (I tested this strange behaviour with the program shown below.)
That is normal. For periodic ones, you'll have to round, if it isn't, the value is within precision.
f.couperin wrote:
[...]
So, why is B slighly inaccurate? Well, if you look at the file, it contains the text:
1.030000000000000e+02
And that's exactly what ReadLn sees. I.e., first the number 1.03 which cannot be represented exactly since floating point numbers (at least IEEE and most other popular formats) are binary, not decimal, and 1.03 in binary is periodic.
Afterwards, it finds `e+02' and multiplies the result by 100 which can be done exactly, but the error was already made.
[...]
Is this really computer dependent or does it depend of the program ? I think that reading 1.030000000000000e+02 as 1030000000000000 * 10^(-15+2) would suppress the problem. Wouldn't it be better ?
In this case yes. But if the number was written as 1.03<thousands of 0s>, this would overflow while the number is perfectly valid.
Sure, things can be improved, but it's not as trivial as it might seem. I don't have the time do think about it now, but if you like to try -- the code is _p_read_longreal in rts/file.c (that's in C, but if you write a better version in Pascal, that's also fine; sooner or later the code will be translated to Pascal, anyway).
What I don't understand is that there is no problem if Readln reads 10.3e+01 in the file (10.3 isn't periodic in binary).
Yes, it is (1001.0period1001). But it doesn't mean there *has* to be an error. Depending on where the binary representation is cut-off, the result (probably rounded to the last valid digit internally) may happen to be right or wrong.
And if it reads 103000e-03 (103000 IS periodic), the value is slightly wrong...
103000 is a whole number (not periodic, or with a period of 0 if you like) and can be represented exactly. But `e-03', i.e. 10**(-3) is not.
OK, we could do 103000 / 10**3 rather than 103000 * 10**(-3)... I'm changing this now (will be uploaded soon), and then this test works indeed...
I'm wondering if there's a way to write a binary (or hexadecimal) representation of the LongReal type in a text file, a clear and understandable representation that could be read back by the program without any difference with the original number. I wrote LongReal numbers to a File Of LongReal, and I translated this file into an hexadecimal representation,
Yes, that's a way to do it. (You could achieve the same within the program, by type casting to an array of bytes or something -- if you need to have a text file. Normally, a file of LongReal would be most appropriate.)
Ernst-Ludwig Bohnen wrote:
I don't know how many bits/bytes this type is using,
BitSizeOf (LongReal) and SizeOf (LongReal). The numbers depend on the platform.
George Shapovalov wrote:
If longReal corresponds to 'extended' on x86, then it is represented by 10 bytes (80
bits). This held since the days of i80387 as I remember.
Yes.
The details of the representation are available in many places, I suppose. They're printed in the BP manual AFAIR, and they're probably also available on the Net.
Frank
And if it reads 103000e-03 (103000 IS periodic), the value is slightly wrong...
103000 is a whole number (not periodic, or with a period of 0 if you like) and can be represented exactly. But `e-03', i.e. 10**(-3) is not.
Afaik whole numbers can be periodic in Floating Point too?
Marco van de Voort wrote:
And if it reads 103000e-03 (103000 IS periodic), the value is slightly wrong...
103000 is a whole number (not periodic, or with a period of 0 if you like) and can be represented exactly. But `e-03', i.e. 10**(-3) is not.
Afaik whole numbers can be periodic in Floating Point too?
Nope, being a whole number is independent of the base. Maybe I should have said integer (but AFAIK, whole number means the same), then it should be more apparent to any programmer that integers can be read and written in any base...
In floating point representations like IEEE, an integer number like 10100101(binary) will be represented as 1.0100101(binary) * 2**7, i.e. exactly, since the exponent is also of base 2.
Maybe what you mean is that integers with more valid digits than can be represented will be cut (e.g. 110000000000000000000000000000001(binary) becomes 1.1(binary) * 2**32 in ShortReal or something). That's true, but it's not really periodic...
Frank
Frank Heckenbach wrote :
[...]
Sure, things can be improved, but it's not as trivial as it might seem. I don't have the time do think about it now, but if you like to try -- the code is _p_read_longreal in rts/file.c (that's in C, but if you write a better version in Pascal, that's also fine; sooner or later the code will be translated to Pascal, anyway).
Thanks. I'm afraid I'm quite unable to write a serious routine but I'll take a look at the problem.
[...]
OK, we could do 103000 / 10**3 rather than 103000 * 10**(-3)... I'm changing this now (will be uploaded soon), and then this test works indeed...
Great. Thanks. I just downloaded the new version and it works fine. In order to understand a little more, may I ask you what did you exactly change in the sources ?
I'm wondering if there's a way to write a binary (or hexadecimal) representation of the LongReal type in a text file, a clear and understandable representation that could be read back by the program without any difference with the original number. I wrote LongReal numbers to a File Of LongReal, and I translated this file into an hexadecimal representation,
Yes, that's a way to do it. (You could achieve the same within the program, by type casting to an array of bytes or something -- if you need to have a text file. Normally, a file of LongReal would be most appropriate.)
I wanted to create a data file that I can read and change into a text editor. What I did to elude the problem : I created a program that can read and write something similar to the "Hex Float" representation I discovered in GCC. There is no more change between the numbers I wrote and the numbers I read into a file. (But the "Hex Float" representation is quite exotic to me...)
[...]
The details of the representation are available in many places, I suppose. They're printed in the BP manual AFAIR, and they're probably also available on the Net.
On my computer (Intel Pentium 120 + Windows 98), "LongReal" is the Intel IEEE Double-Extended wich is 10 bytes long (but stored in 12 bytes : I didn't understand the hidden reason why...). To understand the details of this format, I found a precious help in this web page : http://cch.loria.fr/documentation/IEEE754/numerical_comp_guide/ncg_math.doc. html
--
«Couperin»
f.couperin wrote:
Frank Heckenbach wrote :
[...]
OK, we could do 103000 / 10**3 rather than 103000 * 10**(-3)... I'm changing this now (will be uploaded soon), and then this test works indeed...
Great. Thanks. I just downloaded the new version and it works fine. In order to understand a little more, may I ask you what did you exactly change in the sources ?
The following. However, doing the other things will be a bigger change, possibly affecting more or less the whole function (maybe it'll be better to rewrite it from scratch, but I'm not sure offhand).
--- file.c.orig Mon Apr 9 09:46:36 2001 +++ file.c Wed Apr 4 12:18:32 2001 @@ -2190,24 +2190,24 @@ ch = _p_direct_getc (File); }
- if (enegative) + if (val != 0.0) { - frac = 1.0; - for (i = 1; i <= expon; i++) - frac /= 10.0; - - if (frac == 0.0) - IOERROR (556, 0.0); - - val *= frac; - } - else - for (i = 1; i<= expon; i++) - { - lastval = val; - val = 10.0 * val; - if (!_p_realeq (val / 10.0, lastval)) - IOERROR (556, 0.0); + if (enegative) + { + /* @@ should do square and divide */ + for (i = 1; i <= expon; i++) + val /= 10.0; + if (val == 0.0) /* note that val != 0.0 originally */ + IOERROR (556, 0.0); /*@@ or should we just return 0? */ + } + else + { + /* @@ should do square and multiply */ + for (i = 1; i <= expon; i++) + val *= 10.0; + if (_p_isinf (val) || _p_isnan (val)) + IOERROR (556, 0.0); + } }
}
I'm wondering if there's a way to write a binary (or hexadecimal) representation of the LongReal type in a text file, a clear and understandable representation that could be read back by the program without any difference with the original number. I wrote LongReal numbers to a File Of LongReal, and I translated this file into an hexadecimal representation,
Yes, that's a way to do it. (You could achieve the same within the program, by type casting to an array of bytes or something -- if you need to have a text file. Normally, a file of LongReal would be most appropriate.)
I wanted to create a data file that I can read and change into a text editor. What I did to elude the problem : I created a program that can read and write something similar to the "Hex Float" representation I discovered in GCC. There is no more change between the numbers I wrote and the numbers I read into a file. (But the "Hex Float" representation is quite exotic to me...)
Before I read the last paragraph, I was just going to suggest this, but more as a joke. ;-) Hex (or binary) floats are certainly most appropriate for a computer, but very hard to read (or even change) for most humans...
To read back normal (decimal) floats, you probably need a new reading routine -- either as a replacement in the RTS (see above), or in your own program (i.e., a routine that reads the file char by char and assembles the number).
[...]
The details of the representation are available in many places, I suppose. They're printed in the BP manual AFAIR, and they're probably also available on the Net.
On my computer (Intel Pentium 120 + Windows 98), "LongReal" is the Intel IEEE Double-Extended wich is 10 bytes long (but stored in 12 bytes : I didn't understand the hidden reason why...).
Alignment. For most 32 bit processors (including IA32 in 32 bit mode) it's faster to move (multiples of) 32 bits, i.e. 4 bytes, than 16 bits.
Frank
I wrote :
I don't know if it's really a bug but the result is really surprising. A LongReal variable (of simple integer value) is written into a text file,
[...]
A := 103;
Another information : With a lower integer value, the problem disappears, but with some higher ones (not all...), I get the same problem. (I tested it from 0 to 255.)
-- «Couperin»
On 24 Mar 2001, at 20:17, f.couperin wrote:
I don't know if it's really a bug but the result is really surprising.
[...]
I have : gpc version 20000727, based on 2.95.2 19991024 (release)
Running your program on:
(i386-mingw32msvc) gpc version 20001107, based on 2.95.2 19991024 (release)
...produces "OK". You didn't mention your platform, but perhaps this is a function of the floating-point representation used internally, or perhaps this is a change in GPC from your version to mine.
-- Dave
Running your program on:
(i386-mingw32msvc) gpc version 20001107, based on 2.95.2 19991024 (release)
...produces "OK". You didn't mention your platform, but perhaps this is a function of the floating-point representation used internally, or perhaps this is a change in GPC from your version to mine.
Or the CPU statusword is different across platforms.
On Sun, 25 Mar 2001, J. David Bryan wrote:
On 24 Mar 2001, at 20:17, f.couperin wrote:
I don't know if it's really a bug but the result is really surprising.
[...]
I have : gpc version 20000727, based on 2.95.2 19991024 (release)
Running your program on:
(i386-mingw32msvc) gpc version 20001107, based on 2.95.2 19991024 (release)
...produces "OK". You didn't mention your platform, but perhaps this is a function of the floating-point representation used internally, or perhaps this is a change in GPC from your version to mine.
-- Dave
My platform is PII 400, Linux SuSe 7.1, 'gpc -v' tells me: gpc version 19991030, based on 2.95.2 19991024 (release)
I made some more tests looking on the bit pattern of returned LongReal values (thanks to Frank for his hint to use SizeOf). LongReal uses 64 bits for mantissa and 16 for exponent and sign. If we store enough significant (>20) decimal digits on disk, errors can be found if any, only in the LSB, that's OK. The write statement should look like this: Writeln(TextFile, A:28), nevertheless comparing(=) FP values is walking on glazed frost.
So I take back my suspicion that gpc has some weakness in handling LongReal's (... on PII & Linux).
Ernst-Ludwig
J. David Bryan wrote :
Running your program on:
(i386-mingw32msvc) gpc version 20001107, based on 2.95.2 19991024 (release)
...produces "OK". You didn't mention your platform, but perhaps this is a function of the floating-point representation used internally, or perhaps this is a change in GPC from your version to mine.
My version is now : gpc version 20010331, based on 2.95.2 19991024 (release) My platform : Intel Pentium 120 + Windows 98.
The difference between us is probably due to the floating-point representation. On my machine, LongReal type is the Intel IEEE Double-Extended which has a size of 80 bits (stored in 96 bits). [<SizeOf(LongReal);> gives 12.] I guess it's different on your computer.
-- «Couperin»
On 8 Apr 2001, at 8:01, f.couperin wrote:
My platform : Intel Pentium 120 + Windows 98.
On my machine, LongReal type is the Intel IEEE Double-Extended which has a size of 80 bits (stored in 96 bits). [<SizeOf(LongReal);> gives 12.] I guess it's different on your computer.
I do not think that this is the cause. From the Intel "Software Developer's Manual Volume 1", Chapter 7.1, "Compatibility and Ease of Use of the Intel Architecture FPU:"
"The architecture of the IA FPU has evolved in parallel with the architecture of early IA processors. [...]
"Throughout this evolution, compatibility among the various generations of FPUs and math coprocessors has been maintained. For example, the Pentium Pro processor's FPU is fully compatible with the Pentium and Intel486 DX processors's FPUs."
As we are both running x86 processors, then the difference most likely will be in GPC from my version to yours.
Another possibility: do you have a Pentium processor that has the FDIV bug? See:
http://catless.ncl.ac.uk/Risks/16.57.html#subj2
If so, and if the GPC runtime uses FDIV somewhere in its processing of your program, then perhaps that causing the effect you see.
-- Dave