[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ast-users
Subject:    Re: [ast-users] [prototype-patch] Prototype for correct { |float|, |double|,
From:       Roland Mainz <roland.mainz () nrubsig ! org>
Date:       2013-08-11 22:28:43
Message-ID: CAKAoaQmSWc-6PZCLJOy3U=Sutucygc6F6_h1T6zAL33FrH2=nQ () mail ! gmail ! com
[Download RAW message or body]

On Mon, Aug 12, 2013 at 12:14 AM, Roland Mainz <roland.mainz@nrubsig.org> wrote:
> On Sun, Aug 11, 2013 at 10:57 PM, Roland Mainz <roland.mainz@nrubsig.org> wrote:
>> On Sun, Aug 11, 2013 at 6:15 PM, Cedric Blancher
>> <cedric.blancher@gmail.com> wrote:
>>> On 11 August 2013 10:43, Tina Harriott <tina.harriott.math@gmail.com> wrote:
>>>> On Wed, Jul 24, 2013 at 7:28 PM, Glenn Fowler <gsf@research.att.com> 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()| ...

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) roland.mainz@nrubsig.org
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)

["astksh20130807_short_float_nextafter002.diff.txt" (text/plain)]

diff -r -u original/src/cmd/ksh93/sh/arith.c build_i386_64bit_debug/src/cmd/ksh93/sh/arith.c
--- src/cmd/ksh93/sh/arith.c	2013-06-04 22:14:14.000000000 +0200
+++ src/cmd/ksh93/sh/arith.c	2013-08-11 23:49:21.027203489 +0200
@@ -502,8 +502,12 @@
 		r = nv_getnum(np);
 		if(nv_isattr(np,NV_INTEGER|NV_BINARY)==(NV_INTEGER|NV_BINARY))
 			lvalue->isfloat= (r!=(Sflong_t)r);
+		else if(nv_isattr(np,(NV_DOUBLE|NV_SHORT))==(NV_DOUBLE|NV_SHORT))
+			lvalue->isfloat=2;
+		else if(nv_isattr(np,(NV_DOUBLE|NV_LONG))==(NV_DOUBLE|NV_LONG))
+			lvalue->isfloat=3;
 		else if(nv_isattr(np,NV_DOUBLE)==NV_DOUBLE)
-			lvalue->isfloat=1;
+			lvalue->isfloat=4;
 		if((lvalue->emode&ARITH_ASSIGNOP) && nv_isarray(np))
 			lvalue->nosub = nv_aindex(np)+1;
 		return(r);
diff -r -u original/src/cmd/ksh93/sh/streval.c build_i386_64bit_debug/src/cmd/ksh93/sh/streval.c
--- src/cmd/ksh93/sh/streval.c	2013-07-23 20:48:04.000000000 +0200
+++ src/cmd/ksh93/sh/streval.c	2013-08-12 00:18:58.553584235 +0200
@@ -492,7 +492,44 @@
 			if(c&T_NOFLOAT)
 				num = (*((Math_2f_i)fun))(sp[1],(int)num);
 			else
-				num = (*((Math_2f_f)fun))(sp[1],num);
+			{
+				if (((void*)fun) == ((void*)nextafterl))
+				{
+					switch(node.isfloat)
+					{
+						case 2:
+							num = (nextafterf)((float)sp[1],(float)num);
+							break;
+						case 4:
+							num = (nextafter)((double)sp[1],(double)num);
+							break;
+						default:
+						case 3:
+							num = (nextafterl)((long double)sp[1],(long double)num);
+							break;
+					}
+				}
+				else if (((void*)fun) == ((void*)nexttowardl))
+				{
+					switch(node.isfloat)
+					{
+						case 2:
+							num = (nexttowardf)((float)sp[1],(float)num);
+							break;
+						case 4:
+							num = (nexttoward)((double)sp[1],(double)num);
+							break;
+						default:
+						case 3:
+							num = (nexttowardl)((long double)sp[1],(long double)num);
+							break;
+					}
+				}
+				else
+				{
+					num = (*((Math_2f_f)fun))(sp[1],num);
+				}
+			}
 			break;
 		    case A_CALL2I:
 			sp-=2,tp-=2;


_______________________________________________
ast-users mailing list
ast-users@lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-users


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic