I have a small mc for you:
Write the smallest userrpl program that will round a positive number to its
closest integer, but with a special rule when the fractional part of x is
0.5:
if the integer part of x is even, then round up (usual rule, this is what
the 48/49 does for positive numbers)
if it's odd, then round down.
Some examples, input/output
2 -> 2
0,5 -> 1
1,5 -> 1
1,51 -> 2
2,49 -> 2
The usual rules apply, typeable user-rpl, no STR-> trick, stack handling,
not flag-dependant etc.
Regards
Christian Meland
"integer part", are you sure?
> the 48/49 does for positive numbers)
> if it's odd, then round down.
>
> Some examples, input/output
>
> 2 -> 2
> 0,5 -> 1
> 1,5 -> 1
> 1,51 -> 2
> 2,49 -> 2
>
> The usual rules apply, typeable user-rpl, no STR-> trick, stack handling,
> not flag-dependant etc.
You mean something stupid like this:
<< IF DUP 2 * FP NOT THEN DUP IP 2 MOD - END 0 RND >>
# 4C9Dh 52.5
???
VPN
Look at the examples...
Here's a stupid pdeudocode:
IF fractional_part == 0.5
THEN IF (integer_part MOD 2)= 1 (odd) THEN round down
ELSE (even) round up
ELSE (not of the kind n.5) ordinary round (0 RND)
Chr
"Veli-Pekka Nousiainen" <DROP...@welho.com> skrev i melding
news:bccbkd$o0b$1...@nyytiset.pp.htv.fi...
Hello Christian! Long time no hear (or see ;-)
Actually, the built-in rule is 'round to even', which is the opposite
of what you describe, and in that case a simple solution would be:
\<< -1.E11 SWAP OVER + - \>> 30.5 bytes
Werner
>Hi
>
>I have a small mc for you:
>
>Write the smallest userrpl program that will round a positive number to its
>closest integer, but with a special rule when the fractional part of x is
>0.5:
>
>if the integer part of x is even, then round up (usual rule, this is what
>the 48/49 does for positive numbers)
>if it's odd, then round down.
<snip>
My first try :
48.5 bytes , checksum # 6449h (48)
-------------------------------------------------------------------------------
Jonathan Busby - <j...@SNMAPOhouston.rr.com>
Remove the random permutation of "NOSPAM" from my e-mail address
before replying.
Hm....am I that bad at explaining, or are you bad at understanding, or
both....have been away too long, I think.... :-)
All your program does with my examples is changing the sign....now very
impressive..but hey....with a NEG at the right place.... ;-)
See my other mail for a pseudocode.
Chr
"Werner Huysegoms" <werner-h...@freegates.be> skrev i melding
news:44ec85ff.0306...@posting.google.com...
On Fri, 13 Jun 2003, Christian Meland wrote:
> Write the smallest userrpl program that will round a positive number to its
> closest integer, but with a special rule when the fractional part of x is
> 0.5:
>
> if the integer part of x is even, then round up (usual rule, this is what
> the 48/49 does for positive numbers)
> if it's odd, then round down.
Not tested:
<< 0.5 + DUP IP SWAP FP IF THEN DUP 1 - 2 / FP 2 * - ELSE DROP END >>
--
Erwann ABALEA <erw...@abalea.com> - RSA PGP Key ID: 0x2D0EABD5
-----
j'ai découvert récemment les webcams, mais elles restent fixent.
Quels réglages faut'il réaliser pour les voir en dynamiques ?
-+-GT in : Guide du Neuneu d'Usenet - Silence, on tourne -+-
On Fri, 13 Jun 2003, Erwann ABALEA wrote:
> On Fri, 13 Jun 2003, Christian Meland wrote:
>
> > Write the smallest userrpl program that will round a positive number to its
> > closest integer, but with a special rule when the fractional part of x is
> > 0.5:
> >
> > if the integer part of x is even, then round up (usual rule, this is what
> > the 48/49 does for positive numbers)
> > if it's odd, then round down.
>
> Not tested:
>
> << 0.5 + DUP IP SWAP FP IF THEN DUP 1 - 2 / FP 2 * - ELSE DROP END >>
Correction:
<< 0.5 + DUP IP SWAP FP IF THEN ELSE DUP 1 - 2 / FP 2 * - END >>
75.5 bytes, #C693h
--
Erwann ABALEA <erw...@abalea.com> - RSA PGP Key ID: 0x2D0EABD5
-----
Est-ce un virus ? Je n'arrive pas ą les enlever sauf ce matin oū ils
avaient tous disparus. On a eu une coupure de courant et les fichiers
fantōmes sont revenus. Aidez-nous
-+- in : GNU - La nuit des neuneus vivants qu'on voudrait morts -+-
Jonathan, I don't believe that you've got a UsrRPL-program with less
than 50 bytes. Werner's idea is clever but his program is incorrect. My
following solution is (like Werner's) essentially based on internal
rounding rules (52.5 bytes CRC 49D2):
<< 1. + 1. ALOG SWAP OVER / OVER ALOG DUP ROT + SWAP - * 1. - >>
- Wolfgang
Chr
"Wolfgang Rautenberg" <ra...@math.fu-berlin.de> skrev i melding
news:3EEA00C7...@math.fu-berlin.de...
is only 43b on my 48, so why shouldn't Jonathan have one that's 48,5?
Chr
"Wolfgang Rautenberg" <ra...@math.fu-berlin.de> skrev i melding
news:3EEA00C7...@math.fu-berlin.de...
Here, see for yourself :)
<< 2 INV OVER 2 MOD
IP - DUP2 + FP
:: ABS IFT + FLOOR >>
>Werners (modified) is
><< 1 + NEG -1E11 SWAP OVER + - 1 - >>
>
>is only 43b on my 48
<snip>
And now it's only 42.5 :) :
<< 1 + NEG -1 9 ALOG %T SWAP OVER + - 1 - >>
I think we might be nearing rock bottom here. ;)
The following works as above for positive numbers, but for negative
numbers, if the fractional part is exactly 0.5 (or -0.5, if you prefer),
and the integer part is even, then the number is rounded up instead of
down. To put it another way, if the fractional part is exactly 0.5 (or
-0.5), the the number is rounded to the nearest even integer. Is that
what you're really looking for?
Checksum: # 3CFh
Bytes: 63
%%HP: T(3)A(D)F(.);
\<<
.5 OVER FP ABS == OVER IP 2 MOD NOT
AND { 0 TRNC } IFT
0 RND
\>>
It might be nice to generalize this to work more like RND, with a level
1 argument of -11 through 12. That is, if the only non-zero digit to be
discarded is 5, then round the result so that its last digit is an even
number. I'm sure that I had a program to do this, but I don't find it
offhand, and it was written at least a decade ago, so I doubt that it's
optimal.
--
Regards,
James
.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
Checksum: # 2E18h
Bytes: 58
%%HP: T(3)A(D)F(.);
\<<
.5 OVER FP == OVER IP 2 MOD
AND { 0 TRNC } IFT
0 RND
\>>
--
Regards,
James
Checksum: # 2AC0h
Bytes: 55.5
%%HP: T(3)A(D)F(.);
\<<
.5 OVER FP == OVER IP 2 MOD
IF
AND
THEN
IP
END
0 RND
\>>
Or:
Checksum: # 929h
Bytes: 55.5
%%HP: T(3)A(D)F(.);
\<<
.5 OVER FP == OVER IP 2 MOD
AND
{ IP }
Checksum: #CA7Dh
Bytes: 48.5
%%HP: T(3)A(D)F(.);
\<<
2 INV OVER FP == OVER IP 2 MOD
Interesting, but try either of the above on 1.E12.
--
Regards,
James
> DUP 2 * FP NOT ...
Does it work with:
55555555555.4
55555555555.5
55555555555.6
66666666666.4
66666666666.5
66666666666.6
Etc.
[r->] [OFF]
I see that JHM already beat me to my major problem with your program.
> Mode switching in the 49G makes me nervous:
Well, any time that the 49G's CAS kicks in, I get a bit nervous too. I
was thinking that this was for a 48G series.
The following is for the 49G. It returns a real even if the argument is
a zint.
Checksum: # 4452h
Bytes: 48.5
%%HP: T(3)A(D)F(.);
\<<
2. INV OVER FP == OVER IP 2. MOD
AND
:: IP
IFT
0. RND
\>>
> %%HP: T(3)A(D)F(.);
> \<<
> DUP 2 * FP NOT OVER IP 2 MOD
> AND
> :: IP
> IFT
> 0 RND
> \>>
--
Regards,
James
\\<< 2 INV DUP2 - 2 MOD DUP 1 > - - + \\>
40 bytes
checksum: # 4E2Ch
Chr :-)
"Donald Bachman" <dbac...@ionet.net> skrev i melding
news:716b0838.03061...@posting.google.com...
I'm bad at typing :-(
@NINT
30.5 bytes, 5F46h (49)
\<< -1E11 SWAP OVER - + \>>
Then,
0.5 NINT -> 0.
1.5 NINT -> 2.
those are the built-in rounding rules.
And now I'm going to read the rest of the posts!
Werner
Now I read the other posts as well.
A solution to the problem as you stated it (with round to odd:)
30.5 bytes
#9A3Ch (49)
\<< -100000000001. SWAP OVER - + \>> (the number is -1E11 - 1.)
And to JHM: it works with 99999999999.5 of course.
Cheers,
Werner
Very, very nice.
Only problem I see is that it fails at 1000000000000 (1E12). 8P
But -1.5 NINT -> -1.5
and -0.5 NINT -> -0.5
Is it supposed to work like this?
-1.5 ==> -1.
-0.5 ==> -1.
VPN
From Christian's original post:
"Write the smallest userrpl program that will round a positive number to its
closest integer, but with a special rule when the fractional part of x is
0.5:"
So we need only consider positive integers ;-)
Cheers, Werner
What is the smallest program that will do negatives
correctly also( i.e., normal rounding except that
half-integers get rounded to nearest even integer)?
I was able to get down to 52.5 bytes with a hack free
straightfotrward approach, but someone should be able to
improve on that.
How about this:
<< 2 INV + DUP FLOOR SWAP 2 MOD 0 == - >>
37.5 bytes
FED4 checksum
It should be noted that the reason some of these various algorithms are failing with the
test values of Meyers and Prange is due to a property of the floating point system on the
HP48. There is a largest odd number that can be represented on the 48 and that is
999999999999. Numbers greater than this are all even integers; their fractional parts are
zero. Adding one to a number greater than 999999999999 on the 48 will not change it from
even to odd (these remarks don't apply to internal 15 form numbers; their threshold is
higher). Any algorithm that expects this property (change of parity with addition of
unity) to hold for all integers may fail. So, with this in mind, what should we expect of
a rounding algorithm on the 48? For numbers greater than 999999999999, it should just
return the given integer. With this in mind, a slight recasting of my algorithm above
gives better behavior:
<< 2 INV - DUP CEIL SWAP 2 MOD 0 == + >>
Hi Virgil - as you say, round to *even* again:
bytes : 40.5
check : CB1Eh (49)
\<< DUP FP SIGN -1.E11 * SWAP OVER - + \>>
works for everything I came up with..
If I leave out FP, one case that does not work is 1E12 - 1.
FP ensures that integers are left alone.
Cheers, Werner
fails for 1.E12 - 2. (999999999998.)
BTW, in this case, 0. == can be shortened to NOT
Werner
It fails for every even integer between 1E11 and 999999999999. My first routine failed
for these and also for the cases 1E11 and 1E12. The second routine doesn't fail for 1E11
or 1E12. That's why I said "better" behavior. :-)
Bachman's routine fails for every odd integer in the same range.
I think your technique of testing to see if the input is already an integer is probably
the way to go if you want flawless behavior (at the cost of more bytes, of course).
>BTW, in this case, 0. == can be shortened to NOT
Quite so. I had originally been testing for something other than zero, and when I
changed the comparison to test for zero, I overlooked this saving of 2.5 bytes. So my
routine can be shortened to 35 bytes thanks to your eagle eye.
>
>Werner
>
> Bachman's routine fails for every odd integer in the same range.
>
You know, I hadn't even thought to consider the range where no
fractional part can be represented.
Its larger than what has gone before, but it avoids some of the mess
being discussed:
\<< DUP R->B B->R DUP 2 MOD NOT ROT FP 2 INV == AND - \>>
45 bytes
checksum # F1D3h
doesn't work for negative numbers, or for x > 1E20
Werner
> doesn't work for negative numbers
But there is an "escape clause," which is that
Christian originally asked for a program
to deal only with positive numbers
(and many programmers never deal with
anything more general than they're asked to,
which is why so many narrowly conceived systems are so poor,
and why there were so many Y2K bugs, too :)
> or for x > 1E20
The super-rich are always in a class by themselves, anyway ;-)
Change it to:
\<< DUP 0 RND DUP 2 MOD NOT ROT FP 2 INV == AND - \>>
45 bytes, checksum # D2h
Still doesn't work for negatives (didn't think we were doing them),
but does work for 1E20.
>John H Meyers <jhme...@miu.edu> wrote in message news:<3EF26E16...@miu.edu>...
Posting from a different machine temporarily... ( mine ate itself on
the 19th . Still trying to recover data. )
Here's a solution that I believe works for all non-negative reals :
<< DUP 2 MOD 2 INV -
DUP FP XOR - 0 RND >>
Size : 40 bytes
Checksum : # 8EDCh (48)
Jonathan
> Here's a solution that I believe works for all non-negative reals :
>
> << DUP 2 MOD 2 INV -
> DUP FP XOR - 0 RND >>
>
> Size : 40 bytes
> Checksum : # 8EDCh (48)
>
D'oh! Yeah, the reason for my original program's failure is the impact
of how the HP handles the subtraction of 0.5 from the input number--it
doesn't have enough digits to give an accurate result for 12 digit
inputs and so rounds the result inappropriately. By doing the 2 MOD
first you get around that issue. Nifty.
How about:
<< DUP 2 MOD 2 INV 3 * == - 0 RND >>
37.5 bytes, checksum # FEEEh
I've been waiting to see if my earlier comments about the nature the HP48's representation
of integers would inspire anyone; I hope they did. Now, Busby, Bachman, and Nousiainen's
latest are getting progressively smaller and they do work for all positive integers. But
here is one that is smaller yet and works for negative integers as well:
<< DUP 2 MOD 2 INV == + FLOOR >>
This rounds to odd as requested by the original poster.
With a couple of changes we get:
<< DUP 2 MOD 2 INV == - CEIL >>
This rounds to even, and works for negative integers.
Both are 30 bytes long.
Well I guess there is no reason to '2 INV 3 *' when you can simply '3 2 /'. :)
Yes. Have you?
How embarrassing! It's not the positive integers that are problematical. It's the
positive (and negative) numbers with fractional part OTHER than .5 that don't work right.
This isn't going to be easy to fix without adding bytes. Especially if it is to work with
both negative and positive numbers.
I was so busy getting the right behavior for the special case of fractional parts of
exactly .5 and both positive and negative numbers that I forgot the easy stuff!!
The Virus: Post Now aka VPN is spreading...
VPN
How about the Pentium arithmetic bug?
HP has written papers about software quality assurance, however,
so they never have any of these problems :)
-[]-
Well, after the weekend and some thought, here is the best I can do. Both of the routines
SEEM to work properly with integers with fractional parts of .5 and otherwise. Both
routines work for positive and negative numbers, and are 35 bytes long.
Round to even:
<< 2 INV OVER 2 MOD OVER == - + FLOOR >>
Round to odd:
<< -2 INV OVER -2 MOD OVER == + - FLOOR >>
C'mon beta testers; break 'em or improve 'em!!
>
> Well, after the weekend and some thought, here is the best I can do. Both of the routines
> SEEM to work properly with integers with fractional parts of .5 and otherwise. Both
> routines work for positive and negative numbers, and are 35 bytes long.
>
> Round to even:
>
> << 2 INV OVER 2 MOD OVER == - + FLOOR >>
>
> Round to odd:
>
> << -2 INV OVER -2 MOD OVER == + - FLOOR >>
>
> C'mon beta testers; break 'em or improve 'em!!
The first one fails for 999999999997, as it rounds that whole number
to 999999999998.
The last one fails for 999999999997 as it runs into the aforementioned
problem with handling a 12 digit number and the addition/subtration of
0.5.