On Sun, 11 Aug 2013 22:57:40 +0200 Roland Mainz 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:
> >>>> Here's one of my little tough problems which I am unable to solve
> >>>> myself, even after looking at the source code of ast-ksh. The problem
> >>>> below requires a good understanding how floating point numbers are
> >>>> implemented in computers.
> >>>
> >>>> I'm trying to prototype code and like to iterate over a small, linear
> >>>> area by using the C library function nextafter() to step forward the
> >>>> smallest possible distance between each step, and print the number of
> >>>> iterations needed to cover the distance between 4 and 4.000000000001:
> >>>> ksh -c 'float v ; integer iter ; for ((iter=0,v=4 ; v < 4.000000000001
> >>>> && iter < 10000000; v=nextafter(v,4.000000000001))) ; do
> >>>> ((iter++));done;print $iter '
> >>>> 2305843
> >>>
> >>>> The result 2305843 is correct.
> >>>
> >>>> However, if I use typeset -E (or just typeset) to declare the variable
> >>>> v the loop runs forever, or in this case until it hits iter < 10000000
> >>>> which I added as safeguard later:
> >>>> ksh -c 'typeset -E v ; integer iter ; for ((iter=0,v=4 ; v <
> >>>> 4.000000000001 && iter < 10000000; v=nextafter(v,4.000000000001))) ;
> >>>> do ((iter++));done;print $iter '
> >>>> 10000000
> >>>
> >>>> Can anyone explain this?
> >>>
> >>> float is an alias
> >>> this shows the alias definition
> >>> type float
> >>> which is
> >>> typeset -lE
> >>> this documents -l
> >>> typeset --?l
> >>>
> >>> so for your example
> >>> typeset -E
> >>> gave you a double v and
> >>> typeset -lE
> >>> would give you a "long double" v
> >>
> >> 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.
this looks like the problem
> 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 ?
I'll meet with dgk shortly
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers