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