[Oberon] Fighting a dragon ...

Jörg Straube joerg.straube at iaeth.ch
Tue Jul 16 08:14:57 CEST 2024


Hi

To narrow done where the culprit is, you might know that Wirth’s Oberon compiler has an undocumented feature allowing to write the REALs directly in hex IEEE 754 notation. With this feature you are absolutely sure what REAL we are talking about.
I use this in numerical algorithms, where it is important to have the REAL constants correct to the ulp.
 
CONST pi = 40490FDBR; (* pi is between 40490FDAR and 40490FDBR, closer to the latter *)
Out.Real(40000001R, 12);
Out.RealFix(40000001R, 12, 7)
IF FLT(2) = 40000000R THEN Out.String(“FLT okay”) END;
IF 3.14159265 = pi THEN Out.String(“compiler okay”) ELSE Out.String("compiler bad“) END;

br
Jörg



> Am 16.07.2024 um 02:28 schrieb Hans Klaver <hklaver at dds.nl>:
> 
> Hi Michael & Jörg,
> 
> On 15 jul. 2024, at 23:29 Michael Schierl wrote:
> 
>> Am 15.07.2024 um 22:40 schrieb Hans Klaver:
>>> Hi Jörg,
>>> 
>>> Thanks for this multiplication test.
>>> 
>>> The outcomes are quite remarkable:
>>> 
>>> PdW's emulator without patch indeed gives one wrong* and two correct answers:
>>>   1.9999998
>>>   1.0000001*
>>>   2.0000002
>>> 
>>> But Michael's patched emulator gives three wrong* answers (all around 1 instead of 2):
>>>    .9999999*
>>>   1.0000000*
>>>   1.0000001*
>> 
>> I get three wrong results, regardless whether I use my emulator before
>> or after the patch. Also a very old version of my emulator from 2019
>> returns three wrong results. Do you still have the source of the
>> emulator that returned two correct results?
> 
> I think I do. On 20 Feb. 2020 I installed Peter De Wachter's emulator for the fist time.
> I used a file named oberon-risc-emu-master.zip that I downloaded that same day; its files are dated 22-1-2019.
> 
>> In fact, even when doing
>> 
>> Out.RealFix( FLT(2), 12, 7); Out.Ln;
>> Out.RealFix( FLT(7), 12, 7); Out.Ln;
>> 
>> I get
>>  1.0000000
>>   .8750000
>> 
>> Using Out.Mod by Andreas (which directly calls into Texts.WriteRealFix),
>> so probably that is not the culprit.
> 
> I'm afraid the original Texts.WriteRealFix (also used by Andreas) indeed is the culprit for the latter problem, as indicated by me in a post on this mailing list on 14 Jan. 2023 "REAL I/O in module Texts". My proposal to fix this problem can be found in that post and on my GitHub pages https://github.com/hansklav/Oberon-REAL-IO.
> 
> Actually I forgot to apply these changes in Texts.Mod (which also need my Limits.Mod and Reals.Mod) to the Oberon System disc image I used with Michael's patched emulator.
> Hence the three seemingly wrong results. Sorry for the confusion...
> 
> I used a somewhat extended Multiplication.Mod: 
> 
> MODULE Multiplication;
>  IMPORT Out;
> 
>  PROCEDURE Test*;
>    VAR r: REAL;
>  BEGIN
>    r := 1.45052123;
>    Out.RealFix( r*1.3788146, 14, 7); Out.Hex(ORD(r*1.3788146)); Out.Ln;
>    Out.RealFix( r*1.3788147, 14, 7); Out.Hex(ORD(r*1.3788147)); Out.Ln;
>    Out.RealFix( r*1.3788148, 14, 7); Out.Hex(ORD(r*1.3788148)); Out.Ln;
>    Out.Ln;
>    Out.Real( r*1.3788146, 14);       Out.Hex(ORD(r*1.3788146)); Out.Ln;
>    Out.Real( r*1.3788147, 14);       Out.Hex(ORD(r*1.3788147)); Out.Ln;
>    Out.Real( r*1.3788148, 14);       Out.Hex(ORD(r*1.3788148)); Out.Ln;
>    Out.Ln;
>    Out.RealFix( FLT(2), 14, 7);      Out.Hex(ORD(FLT(2))); Out.Ln;
>    Out.RealFix( FLT(7), 14, 7);      Out.Hex(ORD(FLT(7))); Out.Ln;
>    Out.RealFix( 2.0, 14, 7);         Out.Hex(ORD(2.0));    Out.Ln;
>    Out.RealFix( 7.0, 14, 7);         Out.Hex(ORD(7.0));    Out.Ln
>  END Test;
> 
> END Multiplication.Test
> 
> And I got the following results with Michaels patched emulator and my own Texts.Mod.
> Three correct results for Jörg's lines! (the third column shows the 32-bit floating point value (to at most 9 significant digits if needed) of the hexadecimal number, as verified on https://float.exposed):
> 
>     1.9999998 3FFFFFFE    1.99999976
>     2.0000000 40000000    2.0
>     2.0000002 40000001    2.00000023
> 
>  2.000000E+00 3FFFFFFE
>  2.000000E+00 40000000
>  2.000000E+00 40000001
> 
>     2.0000000 40000000    2.0
>     7.0000000 40E00000    7.0
>     2.0000000 40000000    2.0
>     7.0000000 40E00000    7.0
> 
> And as you can see the problems with Out.RealFix for 2.0 and 7.0 that Michael encountered are also gone.
> 
>> Out.Real works better (in the sense that with my patch, all the values
>> look correct).
> 
> The original Texts.WriteReal works quite OK, with a few small deficiencies (see my GitHub page).
> 
>> Regardless, running the same disk image in my emulator that uses
>> "Native" floating point (on x86_64 on Windows), all expressions work, so
>> I would blame neither the compiler nor Texts.Mod.
> 
> This I cannot explain. Possibly the floating point output routine does not use Texts.Mod.
> 
> Regards,
> 
> Hans
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20240716/d63e380d/attachment.html>


More information about the Oberon mailing list