The HP-71B Math ROM has a nifty function called NEIGHBOR(X,Y) which returns the nearest machine-representable number to X in the direction towards Y. For example, NEIGHBOR(5,7) returns 5.00000000001, and NEIGHBOR(5,1) returns 4.99999999999.
I'm looking for a User RPL implementation of that function. All my attempts fail when X is a power of 10 and Y<X. For example, NEIGHBOR(1,0) should return 0.999999999999 (twelve 9's), but I'm only getting eleven 9's. It's driving me crazier.
Any and all insights will be greatly appreciated.
BTW, I want to use the NEIGHBOR function in an program to be called "UNROUND", which takes any input J (which contains N digits after the decimal point) and returns the smallest and greatest numbers which round to J when N RND is executed. Example: 0.123 UNROUND should yield 0.1225 and 0.123499999999 because those are the smallest and greatest numbers (respectively) which yield 0.123 when 3 RND is executed. If you already have such a program, I'd love to see that too.
There's probably a more elegant way of doing this, but there's some really weird guard digit stuff going on here.
(Try this: 1 5E-12 + 6E-12 + 5E-12 + 5E-12 +. The results are... peculiar.)
Stupid special cases to the rescue. This
seems to be working...
Code:
\<< \-> X Y
\<< X MANT IF DUP 1 SAME Y X < AND THEN -12 ALOG - ELSE
Y X - SIGN -11 ALOG * + END
X XPON ALOG *
\>>
I was working on a very similar solution on the Prime, but when I tested your code on the 48GX I found that it was not working for negative X, one of the reasons being that
-5 MANT returns
5 on the 48, while on the Prime
MANT(-5) returns
-5.
So here is my RPL solution which seems to work for positive and negative numbers:
Code:
« → X Y
« X MANT X SIGN * DUP DUP 1 SAME Y X < *
SWAP -1 SAME X Y < * + 11 + NEG ALOG
Y X - SIGN * + X XPON ALOG *
»
»
And the Prime code:
Code:
EXPORT NEIGHBOR(X,Y)
BEGIN
LOCAL m,n;
m:=MANT(X);
n:=ALOG(−(11+(m=1)*(X>Y)+(m=−1)*(X<Y)));
RETURN (m+n*SIGN(Y-X))*ALOG(XPON(X));
END;
EDIT: Updated to clean RPL code and remove the '\'s.
(06-05-2015 10:04 PM)Dave Britten Wrote: [ -> ]There's probably a more elegant way of doing this, but there's some really weird guard digit stuff going on here.
(Try this: 1 5E-12 + 6E-12 + 5E-12 + 5E-12 +. The results are... peculiar.)
Stupid special cases to the rescue. This seems to be working...
Code:
\<< \-> X Y
\<< X MANT IF DUP 1 SAME Y X < AND THEN -12 ALOG - ELSE
Y X - SIGN -11 ALOG * + END
X XPON ALOG *
\>>
Solves the powers of 10 problem, gets signs wrong.
and NEIGHBOR(0,1)? Should be 1e-499.
I have these:
Code:
@ NXT
@ In: x
@ Out: next number larger than x
\<<
IF DUP THEN DUP XPON ELSE -488 END
ALOG SWAP OVER / @ 10^n s*m
1E-11 OVER -1 SAME ALOG / + *
\>>
@ PRV
@ In: x
@ Out: next number smaller than x
\<< +/- NXT +/- \>>
@ NEIGHBOR
@ In: x y
@ Out: next x in the direction of y
\<< IF OVER < THEN PRV ELSE NXT END \>>
Cheers, Werner
(06-06-2015 12:55 PM)Werner Wrote: [ -> ]and NEIGHBOR(0,1)? Should be 1e-499.
I have these:
Code:
@ NXT
@ In: x
@ Out: next number larger than x
\<<
IF DUP THEN DUP XPON ELSE -488 END
ALOG SWAP OVER / @ 10^n s*m
1E-11 OVER -1 SAME ALOG / + *
\>>
@ PRV
@ In: x
@ Out: next number smaller than x
\<< +/- NXT +/- \>>
@ NEIGHBOR
@ In: x y
@ Out: next x in the direction of y
\<< IF OVER < THEN PRV ELSE NXT END \>>
Cheers, Werner
Powers of ten lack precision.
(06-06-2015 03:03 PM)Gerald H Wrote: [ -> ]Powers of ten lack precision.
? Do you have an example?
Werner
Here my attempt, please be critical - just don't use 0 for input.
Input is one real number, output is the two neighbours.
Code:
DCUT
« DUP SIGN SWAP DUP
NOV 3 PICK * UNROT
NUN *
»
NOV
« DUP XPON ALOG
SWAP MANT -11. ALOG
+ *
»
NUN
« DUP XPON ALOG
SWAP MANT -11. OVER
1 == - ALOG - *
»
(06-06-2015 03:30 PM)Werner Wrote: [ -> ] (06-06-2015 03:03 PM)Gerald H Wrote: [ -> ]Powers of ten lack precision.
? Do you have an example?
Werner
Sorry, I believe I erred - I now believe yours is a complete solution, sadly I realize this too late to obviate my producing my effort above.
Please ignore this posting.
(06-06-2015 12:55 PM)Werner Wrote: [ -> ]and NEIGHBOR(0,1)? Should be 1e-499.
You're right, I've updated my programs:
RPL code:
Code:
« → X Y
« X MANT X SIGN * DUP DUP 1 SAME Y X < *
SWAP -1 SAME X Y < * + 11 + NEG ALOG
Y X - SIGN * + X DUP XPON -488 IFTE ALOG *
»
»
Prime code:
Code:
EXPORT NEIGHBOR(X,Y)
BEGIN
LOCAL m,n;
m:=MANT(X);
n:=ALOG(−(11+(m=1)*(X>Y)+(m=−1)*(X<Y)));
(m+n*SIGN(Y-X))*ALOG(IFTE(X,XPON(X),-488));
END;