<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'><pre>Target.Float is definitely not entire problem, but probably is part of it.<br>Runtime checks are missing also.<br><br> - Jay<br></pre><br><br><div>> From: hosking@cs.purdue.edu<br>> Date: Wed, 4 Sep 2013 12:48:46 -0400<br>> To: mika@async.caltech.edu<br>> CC: m3devel@elegosoft.com<br>> Subject: Re: [M3devel] rounding very large magnitude longreal, time, events?<br>> <br>> So, what is the precise proposal?  Fix Target.Float to avoid constant folding in these instances?  That seems reasonable to me.<br>> <br>> On Sep 4, 2013, at 12:32 PM, mika@async.caltech.edu wrote:<br>> <br>> > Jay K writes:<br>> >> --_ab947ec4-5d41-4d75-ba7b-1dd04573736b_<br>> >> Content-Type: text/plain; charset="iso-8859-1"<br>> >> Content-Transfer-Encoding: quoted-printable<br>> >> <br>> >>> If I am understanding properly what is going on I think this means your n=<br>> >> ew<br>> >>> Modula-3-to-C compiler is the most reasonably behaving Modula-3 implement=<br>> >> ation.<br>> >> <br>> >> <br>> >> I wish=2C but no=2C it is the same as the others.<br>> > <br>> > I see...<br>> > <br>> >> <br>> >> <br>> >> It is all a bit subtle.<br>> > <br>> > As always...<br>> > <br>> >> <br>> > ...<br>> >> <br>> >> <br>> >> I believe=2C based on what you are saying=2C<br>> >> the frontend should generate range checks before<br>> >> floor/trunc/ceiling.<br>> >> <br>> >> Roughly it should be an error to convert<br>> >> a float < FIRST(INTEGER) or > LAST(INTEGER) to a double.<br>> >> Plus or minus one though.<br>> >> <br>> >> <br>> >> That is=2C<br>> >> FLOOR(LAST(INTEGER) + .99999) is ok.<br>> >> CEILING(FIRST(INTEGER) - .99999) is ok.<br>> >> ROUND(LAST(INTEGER) - .499999) is ok.<br>> >> ROUND(FIRST(INTEGER) + .499999) is ok.<br>> >> =20<br>> >> <br>> >> I'm not sure where "round to even" is=2C so -.5 and +.5 might be ok.<br>> >> <br>> >> <br>> >> Oh wait. It depends on the relative ranges of float and integer.<br>> >> <br>> >> <br>> >> In particular=2C a 53bit mantissa longreal converted to a 32bit integer<br>> >> needs the checks I describe. But a 53bit mantissa converted to<br>> >> a 64bit integer=2C no range check is needed.<br>> >> <br>> >> <br>> >> The frontend has some of those optimizations already -- converting<br>> >> from a smaller range to a larger range needs no check.<br>> >> <br>> >> <br>> >> Agreed? Surely this is not a difficult change?<br>> > <br>> > Well, I agree wholeheartedly, yes.<br>> > <br>> >> Nor particularly inefficient?<br>> >> <br>> >> <br>> >> <br>> >> - Jay<br>> >> <br>> >> <br>> >> <br>> >> <br>> >>> To: jay.krell@cornell.edu<br>> >>> Subject: Re: [M3devel] rounding very large magnitude longreal=2C time=2C =<br>> >> events?<br>> >>> Date: Tue=2C 3 Sep 2013 23:42:12 -0700<br>> >>> From: mika@async.caltech.edu<br>> >>> =20<br>> >>> Jay K writes:<br>> >>> ...<br>> >>>> <br>> >>>> Ok=3D2C so this is three dilemnas/questions/bugs in one.<br>> >>>> <br>> >>>> <br>> >>>> http://modula3.elegosoft.com/cm3/doc/reference/complete/html/2_6_10Arith=<br>> >> met=3D<br>> >>>> ic_operations.html<br>> >>>> <br>> >>>> <br>> >>>> ROUND(r) is the nearest integer to r=3D3B ties are broken according to t=<br>> >> he co=3D<br>> >>>> nstant RoundDefault<br>> >>>> <br>> >>>> <br>> >>>> 1) How should ROUND be defined? Is Modula-3 adequately safe here?<br>> >>>> <br>> >>>> <br>> >>>> What should round of numbers less than FIRST(INTEGER)-1=3D20<br>> >>>> or greater than LAST(INTEGER) + 1 round to?=3D20<br>> >>>> <br>> >>>> <br>> >>>> By the simple definition=3D2C they should round to FIRST(INTEGER)=3D20<br>> >>>> and LAST(INTEGER). But is it safe?<br>> >>>> <br>> >>> =20<br>> >>> No=2C I read the definition as saying "integer"=2C not "INTEGER".  That i=<br>> >> s=2C<br>> >>> "integer" is the abstract mathematical concept of an integer=2C not the<br>> >>> Modula-3 data type INTEGER.<br>> >>> =20<br>> >>> I think the intent of the Green Book is that INTEGER should be a range-li=<br>> >> mited<br>> >>> form of integer=2C that is=2C it should behave like an integer as much as=<br>> >> possible=2C<br>> >>> and when the implementation can no longer accomplish that=2C it should si=<br>> >> gnal a=20<br>> >>> runtime error.  =20<br>> >>> =20<br>> >>> It happens that many existing implementions of Modula-3=2C as an implemen=<br>> >> tation<br>> >>> restriction=2C do not handle out-of-range situations correctly.  Things<br>> >>> such as what you describe SHOULD lead to a runtime error=2C value out of =<br>> >> range.<br>> >>> Some implementations wrap instead=2C but I don't even think that's right.=<br>> >> Of<br>> >>> course it's not as bad as it might be in C where you might be indexing an<br>> >>> array with the incorrectly calculated integer and send your program off i=<br>> >> n<br>> >>> never-never land.  In Modula-3 you'll at least get a runtime error at THA=<br>> >> T<br>> >>> point.  But it's still not right.<br>> >>> =20<br>> >>> If I am understanding properly what is going on I think this means your n=<br>> >> ew<br>> >>> Modula-3-to-C compiler is the most reasonably behaving Modula-3 implement=<br>> >> ation.<br>> >>> =20<br>> >>>     Mika<br>> >>                                      =<br>> >> <br>> >> --_ab947ec4-5d41-4d75-ba7b-1dd04573736b_<br>> >> Content-Type: text/html; charset="iso-8859-1"<br>> >> Content-Transfer-Encoding: quoted-printable<br>> >> <br>> >> <html><br>> >> <head><br>> >> <style><!--<br>> >> .hmmessage P<br>> >> {<br>> >> margin:0px=3B<br>> >> padding:0px<br>> >> }<br>> >> body.hmmessage<br>> >> {<br>> >> font-size: 12pt=3B<br>> >> font-family:Calibri<br>> >> }<br>> >> --></style></head><br>> >> <body class=3D'hmmessage'><div dir=3D'ltr'>&gt=3B If I am understanding pro=<br>> >> perly what is going on I think this means your new<br>&gt=3B Modula-3-to-C =<br>> >> compiler is the most reasonably behaving Modula-3 implementation.<br><br><b=<br>> >> r>I wish=2C but no=2C it is the same as the others.<br><br><br>It is all a =<br>> >> bit subtle.<br><br><br>Here is what I believe happens:<br><br><br>I386_NT: =<br>> >> from any double=2C round will give us<br>some integer=2C a 32bit integer=2C=<br>> >> that can be<br>successfully assigned to this range=2C with or without<br>a=<br>> >> range check.<br><br><br>m3cc: Posix: The values are in range.<br>With or w=<br>> >> ithout a range check=2C the code succeeds.<br>For a "few" more years.<br><b=<br>> >> r><br>C backend: Similar.<br>I'm using the C backend all the time on Darwon=<br>> >> .<br>Again=2C Posix: the values are in range.<br>I386_NT: round will give u=<br>> >> s a 32bit integer and it will "work"<br>AMD64_NT: round gives us a 64bit in=<br>> >> teger=2C the range check fails.<br><br><br>In a "few" years=2C 64bit Posix =<br>> >> systems will fail here.<br>32bit Posix would continue to round to some 32bi=<br>> >> t integer=2C which would then<br>successfully pass into the identical subra=<br>> >> nge -- like I386_NT today.<br><br><br><br>The backends don't add range chec=<br>> >> ks.<br>Mostly or entirely=2C they should not.<br>As long as the frontend kn=<br>> >> ows enough=2C it should do it.<br>The frontend knows the range of INTEGER a=<br>> >> nd at least roughly<br>the range of longreal.<br>Possibly the range of a lo=<br>> >> ngreal is target-dependent and knowledge<br>of it should only exist in the =<br>> >> backend. In reality=2C as long as you ignore VAX=2C<br>roughly everything i=<br>> >> s the same since around the early 1980s.<br><br><br><br>I believe=2C based =<br>> >> on what you are saying=2C<br>the frontend should generate range checks befo=<br>> >> re<br>floor/trunc/ceiling.<br><br>Roughly it should be an error to convert<=<br>> >> br>a float &lt=3B FIRST(INTEGER) or &gt=3B LAST(INTEGER) to a double.<br>Pl=<br>> >> us or minus one though.<br><br><br>That is=2C<br>&nbsp=3BFLOOR(LAST(INTEGER=<br>> >> ) + .99999) is ok.<br>&nbsp=3BCEILING(FIRST(INTEGER) - .99999) is ok.<br>&n=<br>> >> bsp=3BROUND(LAST(INTEGER) - .499999) is ok.<br>&nbsp=3BROUND(FIRST(INTEGER)=<br>> >> + .499999) is ok.<br>&nbsp=3B<br><br>I'm not sure where "round to even" is=<br>> >> =2C so -.5 and +.5 might be ok.<br><br><br>Oh wait. It depends on the relat=<br>> >> ive ranges of float and integer.<br><br><br>In particular=2C a 53bit mantis=<br>> >> sa longreal converted to a 32bit integer<br>needs the checks I describe. Bu=<br>> >> t a 53bit mantissa converted to<br>a 64bit integer=2C no range check is nee=<br>> >> ded.<br><br><br>The frontend has some of those optimizations already -- con=<br>> >> verting<br>from a smaller range to a larger range needs no check.<br><br><b=<br>> >> r>Agreed? Surely this is not a difficult change?<br>Nor particularly ineffi=<br>> >> cient?<br><br><br><br>&nbsp=3B- Jay<br><br><br><br><br><div>&gt=3B To: jay.=<br>> >> krell@cornell.edu<br>&gt=3B Subject: Re: [M3devel] rounding very large magn=<br>> >> itude longreal=2C time=2C events?<br>&gt=3B Date: Tue=2C 3 Sep 2013 23:42:1=<br>> >> 2 -0700<br>&gt=3B From: mika@async.caltech.edu<br>&gt=3B <br>&gt=3B Jay K w=<br>> >> rites:<br>&gt=3B ...<br>&gt=3B &gt=3B<br>&gt=3B &gt=3BOk=3D2C so this is th=<br>> >> ree dilemnas/questions/bugs in one.<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B<br>&g=<br>> >> t=3B &gt=3Bhttp://modula3.elegosoft.com/cm3/doc/reference/complete/html/2_6=<br>> >> _10Arithmet=3D<br>&gt=3B &gt=3Bic_operations.html<br>&gt=3B &gt=3B<br>&gt=<br>> >> =3B &gt=3B<br>&gt=3B &gt=3BROUND(r) is the nearest integer to r=3D3B ties a=<br>> >> re broken according to the co=3D<br>&gt=3B &gt=3Bnstant RoundDefault<br>&gt=<br>> >> =3B &gt=3B<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B1) How should ROUND be defined?=<br>> >> Is Modula-3 adequately safe here?<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B<br>&gt=<br>> >> =3B &gt=3B What should round of numbers less than FIRST(INTEGER)-1=3D20<br>=<br>> >> &gt=3B &gt=3B or greater than LAST(INTEGER) + 1 round to?=3D20<br>&gt=3B &g=<br>> >> t=3B<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B By the simple definition=3D2C they s=<br>> >> hould round to FIRST(INTEGER)=3D20<br>&gt=3B &gt=3B and LAST(INTEGER). But =<br>> >> is it safe?<br>&gt=3B &gt=3B<br>&gt=3B <br>&gt=3B No=2C I read the definiti=<br>> >> on as saying "integer"=2C not "INTEGER".  That is=2C<br>&gt=3B "integer" is=<br>> >> the abstract mathematical concept of an integer=2C not the<br>&gt=3B Modul=<br>> >> a-3 data type INTEGER.<br>&gt=3B <br>&gt=3B I think the intent of the Green=<br>> >> Book is that INTEGER should be a range-limited<br>&gt=3B form of integer=<br>> >> =2C that is=2C it should behave like an integer as much as possible=2C<br>&=<br>> >> gt=3B and when the implementation can no longer accomplish that=2C it shoul=<br>> >> d signal a <br>&gt=3B runtime error.   <br>&gt=3B <br>&gt=3B It happens tha=<br>> >> t many existing implementions of Modula-3=2C as an implementation<br>&gt=3B=<br>> >> restriction=2C do not handle out-of-range situations correctly.  Things<br=<br>> >>> &gt=3B such as what you describe SHOULD lead to a runtime error=2C value o=<br>> >> ut of range.<br>&gt=3B Some implementations wrap instead=2C but I don't eve=<br>> >> n think that's right.  Of<br>&gt=3B course it's not as bad as it might be i=<br>> >> n C where you might be indexing an<br>&gt=3B array with the incorrectly cal=<br>> >> culated integer and send your program off in<br>&gt=3B never-never land.  I=<br>> >> n Modula-3 you'll at least get a runtime error at THAT<br>&gt=3B point.  Bu=<br>> >> t it's still not right.<br>&gt=3B <br>&gt=3B If I am understanding properly=<br>> >> what is going on I think this means your new<br>&gt=3B Modula-3-to-C compi=<br>> >> ler is the most reasonably behaving Modula-3 implementation.<br>&gt=3B <br>=<br>> >> &gt=3B      Mika<br></div>                                       </div></body><br>> >> </html>=<br>> >> <br>> >> --_ab947ec4-5d41-4d75-ba7b-1dd04573736b_--<br>> <br></div>                                          </div></body>
</html>