[M3devel] rounding very large magnitude longreal, time, events?
Rodney M. Bates
rodney_bates at lcwb.coop
Fri Sep 6 23:03:50 CEST 2013
On 09/04/2013 12:49 PM, Jay K wrote:
> I want both.
>
>
> We check subrange assignments.
> This seems almost the same thing.
> When a programming converts float to int, what do they accept they are losing?
> Precision or range or both?
> I wonder if it is only precision they accept they are losing, and the loss of range deserves a runtime check.
>
>
> The tradition of ignoring overflows seems unsafe and against the nature of the language. But in the nature of a more efficient less safe implementation.
>
Yes, that's always a dilemma. I tend to prefer accepting some constant-time micro-efficiency
penalties for more predictable and tractable behavior.
>
> Perhaps what I miss is the line between type safety and correctness and lack of later runtime errors?
My definition of safety is that everything that can happen can be defined or understood,
using only the high-level concepts of the language, e.g., abstract values of types and
operators on them, but not machine-level bits, representations, etc. This is contrary
to every textbook and article I have ever read, but the traditional definitions are, IMO,
neither of much use nor consistent with what people seem, informally, to mean by it.
So what ROUND does could be defined using integers and floating point values.
(Some ways of defining it might, however, just refer to bit-level representations.)
> Our obligation is only type safety?
No, safety is not our only obligation. Thinking only in terms of abstract values,
operators could still be poorly defined or defined in ways that are not very
meaningful. Right now, ROUND seems not to be defined for these cases.
> round/trunc/ceiling can return random numbers and still be type safe?
If the random values are members of INTEGER, repeatable, and definable via some
rule that doesn't refer to machine-level representations, that would fit
my definition of type safe, but that is not sufficient for good language design.
As for efficiency, I believe that in this case, either rounding far-out-of-range to a
limit of INTEGER or making it a runtime error would require runtime range checks by the
implementation anyway. The only difference is what to do when the check fails.
Personally, I would like it better if overflows were detected on the arithmetic
operators too. This excludes Word.T, which is, I think the only place the language
forbids it.
> (round converts large positive numbers to FIRST(INTEGER) on I386_NT, seems very dubious...)
>
>
> - Jay
>
>
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--
> Subject: Re: [M3devel] rounding very large magnitude longreal, time, events?
> From: antony.hosking at gmail.com
> Date: Wed, 4 Sep 2013 13:31:01 -0400
> CC: mika at async.caltech.edu; m3devel at elegosoft.com
> To: jay.krell at cornell.edu
>
> I assume you only want the checks to prevent bad folding, not at run-time. In the tradition that overflows are unchecked.
>
> On Sep 4, 2013, at 1:00 PM, Jay K <jay.krell at cornell.edu <mailto:jay.krell at cornell.edu>> wrote:
>
> > Well, I agree wholeheartedly, yes.
>
>
> Tony: can we put in range checks on float to int conversions?
> I'd be ok with initially:
> if float < FIRST(INTEGER) - 1 or float > LAST(INTEGER) + 1
> error
>
> The "1" isn't quite right, but "0" is also wrong.
>
>
> I'd like to see what Java and C# do also (safe/optionally safe languages in good standing).
>
> And then we also have to do something in m3-comm/events to stop it failing on AMD64_NT today and everything else "soon".
>
>
> - Jay
>
>
> > To:jay.krell at cornell.edu <mailto:jay.krell at cornell.edu>
> > Date: Wed, 4 Sep 2013 09:32:17 -0700
> > From:mika at async.caltech.edu <mailto:mika at async.caltech.edu>
> > CC:m3devel at elegosoft.com <mailto:m3devel at elegosoft.com>
> > Subject: Re: [M3devel] rounding very large magnitude longreal, time, events?
> >
> > 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 <mailto: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 <mailto: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 <mailto: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 <mailto: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= <http://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