<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">Hi<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><br></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">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.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">I use this in numerical algorithms, where it is important to have the REAL constants correct to the ulp.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;"> </span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">CONST pi = 40490FDBR; (* pi is between </span><span style="font-size: 14.666667px;">40490FDAR and </span><span style="font-size: 14.666667px;">40490FDBR, closer to the latter *)</span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">Out.Real(40000001R, 12);<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">Out.RealFix(40000001R, 12, 7)<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">IF FLT(2) = 40000000R THEN Out.String(“FLT okay”) END;<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm;"><font face="Aptos, sans-serif" size="3">IF 3.14159265 = pi THEN </font><font face="Aptos, sans-serif"><span style="font-size: 14.666667px;">Out.String(“compiler okay”) ELSE Out.String("compiler bad“) END;</span></font></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;"><br></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">br<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm; font-size: medium; font-family: Aptos, sans-serif;"><span lang="EN-US" style="font-size: 11pt;">Jörg</span></p><div>
<meta charset="UTF-8"><div dir="auto" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div><br></div></div><br class="Apple-interchange-newline">
</div>
<div><br><blockquote type="cite"><div>Am 16.07.2024 um 02:28 schrieb Hans Klaver <hklaver@dds.nl>:</div><br class="Apple-interchange-newline"><div><div>Hi Michael & Jörg,<br><br>On 15 jul. 2024, at 23:29 Michael Schierl wrote:<br><br><blockquote type="cite">Am 15.07.2024 um 22:40 schrieb Hans Klaver:<br><blockquote type="cite">Hi Jörg,<br><br>Thanks for this multiplication test.<br><br>The outcomes are quite remarkable:<br><br>PdW's emulator without patch indeed gives one wrong* and two correct answers:<br> 1.9999998<br> 1.0000001*<br> 2.0000002<br><br>But Michael's patched emulator gives three wrong* answers (all around 1 instead of 2):<br> .9999999*<br> 1.0000000*<br> 1.0000001*<br></blockquote><br>I get three wrong results, regardless whether I use my emulator before<br>or after the patch. Also a very old version of my emulator from 2019<br>returns three wrong results. Do you still have the source of the<br>emulator that returned two correct results?<br></blockquote><br>I think I do. On 20 Feb. 2020 I installed Peter De Wachter's emulator for the fist time.<br>I used a file named oberon-risc-emu-master.zip that I downloaded that same day; its files are dated 22-1-2019.<br><br><blockquote type="cite">In fact, even when doing<br><br>Out.RealFix( FLT(2), 12, 7); Out.Ln;<br>Out.RealFix( FLT(7), 12, 7); Out.Ln;<br><br>I get<br> 1.0000000<br> .8750000<br><br>Using Out.Mod by Andreas (which directly calls into Texts.WriteRealFix),<br>so probably that is not the culprit.<br></blockquote><br>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.<br><br>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.<br>Hence the three seemingly wrong results. Sorry for the confusion...<br><br>I used a somewhat extended Multiplication.Mod: <br><br>MODULE Multiplication;<br> IMPORT Out;<br><br> PROCEDURE Test*;<br> VAR r: REAL;<br> BEGIN<br> r := 1.45052123;<br> Out.RealFix( r*1.3788146, 14, 7); Out.Hex(ORD(r*1.3788146)); Out.Ln;<br> Out.RealFix( r*1.3788147, 14, 7); Out.Hex(ORD(r*1.3788147)); Out.Ln;<br> Out.RealFix( r*1.3788148, 14, 7); Out.Hex(ORD(r*1.3788148)); Out.Ln;<br> Out.Ln;<br> Out.Real( r*1.3788146, 14); Out.Hex(ORD(r*1.3788146)); Out.Ln;<br> Out.Real( r*1.3788147, 14); Out.Hex(ORD(r*1.3788147)); Out.Ln;<br> Out.Real( r*1.3788148, 14); Out.Hex(ORD(r*1.3788148)); Out.Ln;<br> Out.Ln;<br> Out.RealFix( FLT(2), 14, 7); Out.Hex(ORD(FLT(2))); Out.Ln;<br> Out.RealFix( FLT(7), 14, 7); Out.Hex(ORD(FLT(7))); Out.Ln;<br> Out.RealFix( 2.0, 14, 7); Out.Hex(ORD(2.0)); Out.Ln;<br> Out.RealFix( 7.0, 14, 7); Out.Hex(ORD(7.0)); Out.Ln<br> END Test;<br><br>END Multiplication.Test<br><br>And I got the following results with Michaels patched emulator and my own Texts.Mod.<br>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):<br><br> 1.9999998 3FFFFFFE 1.99999976<br> 2.0000000 40000000 2.0<br> 2.0000002 40000001 2.00000023<br><br> 2.000000E+00 3FFFFFFE<br> 2.000000E+00 40000000<br> 2.000000E+00 40000001<br><br> 2.0000000 40000000 2.0<br> 7.0000000 40E00000 7.0<br> 2.0000000 40000000 2.0<br> 7.0000000 40E00000 7.0<br><br>And as you can see the problems with Out.RealFix for 2.0 and 7.0 that Michael encountered are also gone.<br><br><blockquote type="cite">Out.Real works better (in the sense that with my patch, all the values<br>look correct).<br></blockquote><br>The original Texts.WriteReal works quite OK, with a few small deficiencies (see my GitHub page).<br><br><blockquote type="cite">Regardless, running the same disk image in my emulator that uses<br>"Native" floating point (on x86_64 on Windows), all expressions work, so<br>I would blame neither the compiler nor Texts.Mod.<br></blockquote><br>This I cannot explain. Possibly the floating point output routine does not use Texts.Mod.<br><br>Regards,<br><br>Hans<br><br></div></div></blockquote></div><br></body></html>