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.
The test still doesn't work: 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 ~/bin/ksh --version version sh (AT&T Research) 93v- 2013-09-13 ~/bin/ksh x.sh 10000000 Is it very hard to integrate the fix Mr. Mainz send? My professor is asking for a solution (ksh, or switch to perl or python) Tina -- Tina Harriott - Women in Mathematics Contact: tina.harriott.m...@gmail.com _______________________________________________ ast-users mailing list ast-users@lists.research.att.com http://lists.research.att.com/mailman/listinfo/ast-users