On Mon, 12 Aug 2013 07:29:08 +0200 Irek Szczesniak wrote: > On Mon, Aug 12, 2013 at 1:16 AM, Roland Mainz <[email protected]> > wrote: > > On Mon, Aug 12, 2013 at 12:28 AM, Roland Mainz <[email protected]> > > wrote: > > [Removing [email protected]] > >> On Mon, Aug 12, 2013 at 12:14 AM, Roland Mainz <[email protected]> > >> wrote: > >>> On Sun, Aug 11, 2013 at 10:57 PM, Roland Mainz <[email protected]> > >>> wrote: > >>>> On Sun, Aug 11, 2013 at 6:15 PM, Cedric Blancher > >>>> <[email protected]> wrote: > >>>>> On 11 August 2013 10:43, Tina Harriott <[email protected]> > >>>>> wrote: > >>>>>> On Wed, Jul 24, 2013 at 7:28 PM, Glenn Fowler <[email protected]> > >>>>>> wrote: > >>>>>>> On Wed, 24 Jul 2013 19:02:39 +0200 Tina Harriott wrote: > >>> [snip] > >>>>>> But why does nextafter() misbehave if I want to use a datatype smaller > >>>>>> than "long double"? Accuracy is a good thing, but in this case we > >>>>>> iterate too fine-grained, meaning the code should iterate over the > >>>>>> smallest possible steps of a double, but not over the smallest > >>>>>> possible steps of a long double. > >>>>> > >>>>> Does anyone have a good idea how to fix this in ksh? > >>>> > >>>> Grumpf... yes. Technically I feared that day may come when > >>>> |nextafter()| and |nexttoward()| were added in ksh93... ;-/ > >>>> > >>>> The issue is more or less like this: Both |nextafter(f|l|)\(\)| and > >>>> |nexttoward(f|l|)\(\)| step over the smallest possible quantity for > >>>> the specific { |float|, |double|, |long double| }-datatype and > >>>> therefore (for example) using |nextafterl()| (intended for |long > >>>> double|) for a |float| doesn't work because it does so small steps > >>>> that they cannot be represented in a |float| ... that causes the > >>>> endless loop in Tina's example. > >>>> > >>>> The fix would be to "remember" the datatype (e.g. { |float|, > >>>> |double|, |long double| }) for a given variable and pass that down to > >>>> |arith_exec()| and call the specific version of |nextafter()| and > >>>> |nexttoward()| for that datatype, for example: > >>>> - variables declared via typeset -s -E/-X should use > >>>> |nextafterf()|/|nexttowardf()| > >>>> - variables declared via typeset -E/-X should use > >>>> |nextafter()|/|nexttoward()| > >>>> - variables declared via typeset -l -E/-X should use > >>>> |nextafterl()|/|nexttowardl()| > >>>> ... if the platforms libc/libm do not have a matching > >>>> |nextafter(f|l|)\(\)|/|nexttoward(f|l|)\(\)| variant for the input > >>>> datatype then the "function not found"-error should be thrown. > >>>> > >>>> Note that we do _not_ have to change the logic for all math > >>>> functions... AFAIK |nextafter()| and |nexttoward()| are the only > >>>> exceptions which require special handling... > >>>> > >>>> Glenn: What do you think ? > >>> > >>> Attached (as "astksh20130807_short_float_nextafter001.diff.txt") is a > >>> _prototype_ patch which shows how it would look like: > >>> -- snip -- > >>> $ ksh -c 'typeset -s -E x=4 ; print $(( x=nextafter(x,5) ))' > >>> 4.0000004768371582 > >>> $ ksh -c 'typeset -E x=4 ; print $(( x=nextafter(x,5) ))' > >>> 4.00000000000000089 > >>> $ ksh -c 'typeset -l -E x=4 ; print $(( x=nextafter(x,5) ))' > >>> 4 # this is not exactly 4 but it is so a tiny step away from 4 that > >>> normal %f output doesn't recognise it > >>> -- snip -- > >>> > >>> * ToDo: > >>> - Add |nexttoward()| support > >>> - Add defines for type size (|float|, |double|, |long double|) > >>> - Add error code in case if one of the { |float|, |double|, |long > >>> double| }-variants is missing > >>> - Somehow make the code look better > >>> > >>> Comments/rants/feedback welcome... > >> > >> Grumpf... attached (as > >> "astksh20130807_short_float_nextafter002.diff.txt") is a fixed > >> patch... the previous one used |double| in case that the datatype of > >> the arguments couldn't be obtained... the patch corrects this and adds > >> support for |nexttoward()| ... > > > > More thought about this: > > src/cmd/ksh93/data/math.tab could return all three variants (for { > > |float|, |double|, |long double| }) and |fun| in |arith_exec()| would > > be a pointer to an array of these three variants. That would make the > > support for |float| and |double| generic and remove all the > > |if()|/|switch()| mess from the "hot" codepath...
> That is IMO the only solution which covers *all* corner cases, i.e. if > an overflow/underflow or creation of subnormal numbers in a math > function happens. Smaller datatypes mean you'll hit the limits earlier > than for larger datatypes and not all float/double functions behave > like doing the same operation with a long double datatype and then > cast the result to the requested datatype. a related question does posix fprintf(3) have a way to print (float) values? I looked a few times and didn't find any _______________________________________________ ast-developers mailing list [email protected] http://lists.research.att.com/mailman/listinfo/ast-developers
