HP Forums
NEIGHBOR function in RPL - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: General Forum (/forum-4.html)
+--- Thread: NEIGHBOR function in RPL (/thread-4089.html)



NEIGHBOR function in RPL - Joe Horn - 06-05-2015 09:03 PM

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.


RE: NEIGHBOR function in RPL - Dave Britten - 06-05-2015 10:04 PM

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 *
\>>



RE: NEIGHBOR function in RPL - Didier Lachieze - 06-05-2015 11:35 PM

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.


RE: NEIGHBOR function in RPL - Gerald H - 06-06-2015 09:17 AM

(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.


RE: NEIGHBOR function in RPL - Werner - 06-06-2015 12:55 PM

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


RE: NEIGHBOR function in RPL - Gerald H - 06-06-2015 03:03 PM

(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.


RE: NEIGHBOR function in RPL - Werner - 06-06-2015 03:30 PM

(06-06-2015 03:03 PM)Gerald H Wrote:  Powers of ten lack precision.

? Do you have an example?
Werner


RE: NEIGHBOR function in RPL - Gerald H - 06-06-2015 03:41 PM

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 - *
»



RE: NEIGHBOR function in RPL - Gerald H - 06-06-2015 03:45 PM

(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.


RE: NEIGHBOR function in RPL - Gerald H - 06-06-2015 03:50 PM

Please ignore this posting.


RE: NEIGHBOR function in RPL - Didier Lachieze - 06-06-2015 10:57 PM

(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;