David send Roland a comment that nextafter(x+1.1,5) does not figure
the data type of x+1.1 correctly and always uses the data type of the
right value.

IMO the rules of ISO C (C1X) should apply.

The difficult part is that I do not know how to do that with the
arithmetic engine in ksh, some how the value of node.isfloat (which is
now a kind of enum describing which kind of floating point data type
is used - float, double, long double) must be recalculated based on
the left hand lhand_node.isfloat and right hand rhand_node.isfloat
value of such operations.

Olga

On Mon, Aug 12, 2013 at 6:36 PM, Glenn Fowler <g...@research.att.com> wrote:
>
> On Sun, 11 Aug 2013 22:57:40 +0200 Roland Mainz wrote:
>> On Sun, Aug 11, 2013 at 6:15 PM, Cedric Blancher
>> <cedric.blanc...@gmail.com> wrote:
>> > On 11 August 2013 10:43, Tina Harriott <tina.harriott.m...@gmail.com> 
>> > wrote:
>> >> On Wed, Jul 24, 2013 at 7:28 PM, Glenn Fowler <g...@research.att.com> 
>> >> 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-users mailing list
> ast-users@lists.research.att.com
> http://lists.research.att.com/mailman/listinfo/ast-users



-- 
      ,   _                                    _   ,
     { \/`o;====-    Olga Kryzhanovska   -====;o`\/ }
.----'-/`-/     olga.kryzhanov...@gmail.com   \-`\-'----.
 `'-..-| /       http://twitter.com/fleyta     \ |-..-'`
      /\/\     Solaris/BSD//C/C++ programmer   /\/\
      `--`                                      `--`
_______________________________________________
ast-users mailing list
ast-users@lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to