Re: ESL - math.e - rounding
- Posted by "Juergen Luethje" <j.lue at gmx.de> Aug 05, 2005
- 558 views
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. > 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