Re: ESL - math.e - rounding
- Posted by "Christian Cuvier" <christian.cuvier at agriculture.gouv.fr> Aug 05, 2005
- 768 views
> Date: Fri, 05 Aug 2005 09:26:03 +0200 From: "Juergen Luethje" <j.lue at > gmx.de> Subject: Re: ESL - math.e - rounding Christian Cuvier wrote: > >>>>> From: "Juergen Luethje" >>>>> >>>>> Christian Cuvier wrote: >>>>> >>>>> <snip> >>>>> >>> >>>>>>>>> In theory, we need the 4 rounding modes below. >>> >>>>> >>>>> I think we should have all 4 rounding modes in the ESL, shouldn't we? >>>>> >>> >>>>>>>>> And the Intel FP architecture supports them all. >>>>>>>>> >>>>>>>>> [Quoting from Intel FPU documentation] >>>>>>>>> >>>>>>>>> Table 4-8. Rounding Modes and Encoding of Rounding Control (RC) Field >>>>>>>>> >>>>>>>>> -------------------------------------------------------------------- >>>>>>>>> Rounding ! RC Field ! Setting Description >>>>>>>>> Mode ! ! >>>>>>>>> ---------------+----------+---------------------------------------- >>>>>>>>> ! ! Rounded result is the closest to the >>>>>>>>> Round to ! 00B ! infinitely precise result. If two values >>>>>>>>> nearest (even) ! ! are equally close, the result is the even >>>>>>>>> ! ! value (that is, the one with the >>>>>>>>> ! ! least-significant bit of zero). Default >>>>>>>>> ---------------+----------+------------------------------------------ >>>>>>>>> Round down ! ! Rounded result is closest to but no >>>>>>>>> greater >>>>>>>>> (toward =E2=88=92=E2=88=9E) ! 01B !than the infinitely precise >>>>>>>>> resu= >>>>>>>>> lt. >>>>>>>>> ---------------+----------+------------------------------------------ >>>>>>>>> Round up ! ! Rounded result is closest to but no less >>>>>>>>> (toward +=E2=88=9E) ! 10B !than the infinitely precise result. >>>>>>>>> ---------------+----------+------------------------------------------ >>>>>>>>> Round toward ! ! Rounded result is closest to but no >>>>>>>>> greater >>>>>>>>> zero (Truncate)! 11B ! in absolute value than the infinitely >>>>>>>>> precise >>>>>>>>> >>>>>>>>> ! ! result. >>>>>>>>> --------------------------------------------------------------------- >>> >>>>> >>>>> Interesting, thanks for the information. >>>>> It looks as if this must be programmed by using special FP assembler >>>>> instructions. So this is no job for me ... >>>>> >> >>> Yes and no. >>> >>> The rounding modes described above may apply to two different things: >>> the internal operation of the FPU and the programmer-level functions. >>> >>> For the former, you have to play with the fstcw ax and fldcw ax machine >>> instructions, by setting the appropriate bits in the ax register in between. > > > In the table above there often is the term "infinitely precise result". > Euphoria has a limited precision, and therefore doesn't know > the infinitely precise result. That's why I assumed it must be done by > using special assembler/machine instructions. > Well, computers are finite state machines, so they never achieve infinite precision. What Inetl calls "infinite precision result" is a reusult stored with all available bits (80, versus 64 for a double precision floating number). If you want strict conformance with IEEE when rounding large atoms in any rounding mode, then you may need the asm tweak. And due to the overhead of call() in Euphoria (yet another thorn), that won't be too efficient. But is strict conformance with IEEE a real concern? Note that the asm tweak could be optimised if the ESL could be shipped with a .so/.dll implementing these sorts of machine dependent stuff. Not sure it is a good idea at all (could be however if such issues start cropping up), and certainly not for a first release! CChris > >>> For programmer level functions, there's hardly any need to tweak the FPU >>> directly, except in extreme cases. >>> >>> A function generic_round(atom what, integer places,integer mode), which >>> would be wrapped in various ways, would return as follows: >>> >>> what=7.126, places=2 >>> mode 0 -> 7.13 >>> 1 -> 7.12 >>> 2 -> 7.13 >>> 3 -> 7.12 >>> >>> what=-7.126, places=2 >>> mode 0 -> -7.13 >>> 1 -> -7.13 >>> 2 -> -7.12 >>> 3 -> -7.12 >>> >>> Everything can be done using floor(), sgn() and abs(), except that it is >>> a bit tedious to write the wrappers and RDS doesn't provide abs() nor sgn(). > > > Thanks for your precise example above. Now I see, that we are talking > about different functions here. I'll try to clarify what I meant: > > I was meaning the functions > round_half_up (what, places) > round_half_even(what, places) > round_half_down(what, places) > > which in almost all cases return the same results!!! > > -- Example 1 > what = 7.126, places = 2 > round_half_up (what, places) -> 7.13 > round_half_even(what, places) -> 7.13 > round_half_down(what, places) -> 7.13 > > what = -7.126, places = 2 > round_half_up (what, places) -> -7.13 > round_half_even(what, places) -> -7.13 > round_half_down(what, places) -> -7.13 > > > The functions only might return different results, when the > (places+1)th digit is '5', and no more digits are following. > That's why there is the word 'half' in their names. I deliberately > did *not* name them > round_up () > round_even() > round_down() > (as someone previously had assumed). > > > -- Example 2 > what = 7.125, places = 2 > round_half_up (what, places) -> 7.13 > round_half_even(what, places) -> 7.12 > round_half_down(what, places) -> 7.12 > > what = -7.125, places = 2 > round_half_up (what, places) -> -7.13 > round_half_even(what, places) -> -7.12 > round_half_down(what, places) -> -7.12 > > > -- Example 3 > what = 7.135, places = 2 > round_half_up (what, places) -> 7.14 > round_half_even(what, places) -> 7.14 > round_half_down(what, places) -> 7.13 > > what = -7.135, places = 2 > round_half_up (what, places) -> -7.14 > round_half_even(what, places) -> -7.14 > round_half_down(what, places) -> -7.13 > > > For instance PowerBASIC's round() function works like > the round_half_even() function. This is according to > IEEE standards. > > <snip> > > Regards, > Juergen