The Museum of HP Calculators

HP Forum Archive 18

[ Return to Index | Top of Index ]

Problem with tiny HP-16C program - can you debug this?
Message #1 Posted by Richard B on 5 July 2008, 6:28 p.m.

The software library here has an excellent program with two routines that switch from floating mode to integer mode or back. It says that if the floating value is non integer it will be truncated. Unfortunately there is a bug in it. Sometimes it will truncate, e.g. 1234.567 will convert to 1234 correctly. But 1.2 converts to 872415233 decimal, instead of 1. I can't get my mind around what is happening. Can you help? Or suggest coding to work around the problem?

The reason this is an issue is that if for example you are in float mode with 3 decimal places and the number is 1.0001, you see it as 1.000. But it will convert incorrectly.

Here is the code:

# HP-16C Integer-to-Float/Float-to-Integer
#      -Jamie Cox
# Usage: 
# Press GSB A to convert a float number to 32-bit HEX
# Press GSB 9 to convert an integer to float
# Mnemonic: A is a hex digit, 9 is a decimal digit. 
#   A & 9 are at opposite ends of the keypad 
#
# 

001 43,22,A g LBL A # Convert Float to Integer 002 23 HEX # Leaves value in Y and shift count in X 003 42 F RRn # Apply shift 004 2 2 # 20 Hex gives 32-bit wordsize 005 0 0 006 42 44 f WSIZE 007 43,4,3 g SF 3 # display leading zeros 008 43 21 g RTN

009 43,22,9 g LBL 9 # Convert Integer to Float 010 0 0 011 42, 45,3 f FLOAT 3 # Set # digits after decimal 012 43 21 g RTN # That was easy

Edited: 5 July 2008, 6:30 p.m.

      
Re: Problem with tiny HP-16C program - can you debug this?
Message #2 Posted by Chris Dean on 6 July 2008, 2:46 p.m.,
in response to message #1 by Richard B

Starting with 1.2 could you document the values at each stage.

            
Re: Problem with tiny HP-16C program - can you debug this?
Message #3 Posted by Richard B on 6 July 2008, 3:49 p.m.,
in response to message #2 by Chris Dean

OK here we go. (Window 1 gives us the high order part in each case)

We are in float mode.
1.2

HEX FFFFFFE1 .h (checking window 1 shows FFFFFF)

You also need to know Y at this stage. It shows: 9999999A .h (checking window 1 shows 000000)

RRn 34000001 .h (checking window 1 shows 333333)

The rest just changes with word size from 56 to 32 and sets it to display leading zeroes

The result in decimal is 14411518821007361 which is nowhere near 1!

Here is the same but starting with 2 2

HEX FFFFFFE2 (window 1 is FFFFFF)

Y is 80000000 (window 1 is 000000)

RRn 00000002 .h (window 1 is 000000) Correct result.

Edited: 6 July 2008, 3:51 p.m.

      
Re: Problem with tiny HP-16C program - can you debug this?
Message #4 Posted by Katie Wasserman on 6 July 2008, 4:19 p.m.,
in response to message #1 by Richard B

I think that RRn (Rotate-right-N) isn't the way to do this, you need to shift-right-N but this requires some looping because there isn't a SRn function on the 16C. However there's a way to obtain the integer part of a number in floating point mode follow this link. Once you have the integer part in floating point mode you can use RRn when you're back in integer mode and you'll get the right answer.

            
Re: Problem with tiny HP-16C program - can you debug this?
Message #5 Posted by Walter B on 6 July 2008, 6:40 p.m.,
in response to message #4 by Katie Wasserman

The program described in this link works definitively on a 16c (just tested).

            
Re: Problem with tiny HP-16C program - can you debug this?
Message #6 Posted by Richard B on 6 July 2008, 6:46 p.m.,
in response to message #4 by Katie Wasserman

Thanks. That gives useful code that one can add to force it to an integer before converting.

It is very good to learn how to do an RND in 5 steps or an INT in 15 steps (for positive numbers); I did not know how to do that.

It would be still be good to try to make the conversion work as it should - perhaps using SR as you suggest. Also the conversion doesn't handle negative numbers at the moment - they come out positive. (The opposite conversion, to float, has no problems and does handle negative numbers.)

                  
Re: Problem with tiny HP-16C program - can you debug this?
Message #7 Posted by Richard B on 7 July 2008, 10:09 a.m.,
in response to message #6 by Richard B

I have finally solved it. This proved to be quite difficult. By solved it I mean that it must work correctly in all conditions:

- Both positive and negative numbers.
- Fractional numbers must convert correctly with the fractional part removed.
- It must work with negative numbers in both 1's complement and 2's complement.
- It must work if using 64 bit wordsize.

Possible methods: - RRn is only suitable if the value is an integer already. Does not work with negatives. - SR in a loop is better but does not work with negatives. - Divide by 2 in a loop does not work with negatives. - ASR works with positives and negatives, but if in 2's complement mode a fractional negative number gives the wrong result, e.g. -1.2 becomes -2.

Solution: - Use ASR in a loop - Capture the sign in a flag and restore at the end.

The solution takes about 19 steps.

I can see quite a neat way to split this into routines and package it with an INT and a RND function (and the simple int to float function) that will also work correctly in all conditions. The whole lot should take about 50 steps.

Thanks for your help. I'll put the final versions in a message here and offer them to the library.

Edited: 7 July 2008, 10:13 a.m.

                        
Re: Problem with tiny HP-16C program - can you debug this?
Message #8 Posted by Richard B on 7 July 2008, 1:41 p.m.,
in response to message #7 by Richard B

Here is the debugged code to switch between float and int. Any suggestions very welcome.

Step	ListKey	Mnemo	Comments
001	43,22,a	g LBL A	Float to Int
002	43,5,2	g CF 2	Store sign
003	43 2	g x<0	
004	43,4,2	g SF 2	
005	43 8	g ABS	
006	23	HEX	Convert
007	43 8	g ABS	
008	44 32	STO I	
009	34	x<>y	
010	43,22,1	g LBL 1	
011	43 b	g ASR	
012	43 23	g DSZ	
013	22 1	GTO 1	
014	0	0	Set wordsize to 64
015	42 44	f WSIZE	
016	43,6,2	g F? 2	Restore sign
017	49	CHS	
018	43,4,3	g SF 3	Show leading zeroes
019	43 21	g RTN	
020	43,22,9	g LBL 9	Int to Float
021	0	0	
022	42,45,4	f FLOAT 4	Number of decimal places
023	43 21	g RTN	

                        
Re: Problem with tiny HP-16C program - can you debug this?
Message #9 Posted by Richard B on 7 July 2008, 1:46 p.m.,
in response to message #7 by Richard B

Here is the same debugged code to switch between Float and Int. This time it is integrated with routines for INT and RND. All suggestions very welcome.

Instructions:
GSB A Float to Int
GSB 9 Int to Float
GSB B INT
GSB D RND

Step ListKey Mnemo Comments 001 43,22,2 g LBL 2 Subroutine to store sign 002 43,5,2 g CF 2 003 43 2 g x<0 004 43,4,2 g SF 2 005 43 8 g ABS 006 43 21 g RTN 007 43,22,3 g LBL 3 Subroutine to round 008 42 49 f EEX 009 9 9 010 40 + 011 43 36 g LSTx 012 30 - 013 43 21 g RTN 014 43,22,a g LBL A Float to Int 015 21 2 GSB 2 016 23 HEX Convert 017 43 8 g ABS 018 44 32 STO I 019 34 x<>y 020 43,22,1 g LBL 1 021 43 b g ASR 022 43 23 g DSZ 023 22 1 GTO 1 024 0 0 Set wordsize to 64 025 42 44 f WSIZE 026 43,4,3 g SF 3 027 43,22,4 g LBL 4 028 43,6,2 g F? 2 Restore sign 029 49 CHS 030 43,4,3 g SF 3 Show leading zeroes 031 43 21 g RTN 032 43,22,b g LBL B INT 033 21 2 GSB 2 034 21 3 GSB 3 035 43 3 g x>y Adjust rounded result by 1 036 1 1 037 0 0 038 36 Enter 039 1 1 040 0 0 041 10 / 042 30 - 043 22 4 GTO 4 044 43,22,d g LBL D RND 045 21 2 GSB 2 046 21 3 GSB 3 047 22 4 GTO 4 048 43,22,9 g LBL 9 Int to Float 049 0 0 050 42,45,4 f FLOAT 4 Number of decimal places 051 43 21 g RTN


[ Return to Index | Top of Index ]

Go back to the main exhibit hall