Problem with tiny HP-16C program - can you debug this?



#10

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.


#11

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


#12

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.

#13

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.


#14

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

#15

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


#16

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.


#17

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

#18

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


Possibly Related Threads...
Thread Author Replies Views Last Post
  Bought a 16C to compensate a little Eelco Rouw 23 2,474 12-07-2013, 01:26 PM
Last Post: Eelco Rouw
  HP Prime: problem with the memory of calculator during the debug process? Carlos CM (Mexico) 7 1,139 12-06-2013, 12:34 PM
Last Post: Carlos CM (Mexico)
  Problem with debug HP prime program, somebody help me? Carlos CM (Mexico) 6 1,057 12-05-2013, 03:07 PM
Last Post: Carlos CM (Mexico)
  HP Prime: run a program in another program Davi Ribeiro de Oliveira 6 808 11-11-2013, 08:28 PM
Last Post: Davi Ribeiro de Oliveira
  Shiny new 16C! Keith Midson 7 862 10-27-2013, 02:22 AM
Last Post: Keith Midson
  Prime: Debug with Parameters Helge Gabert 8 853 10-06-2013, 07:26 PM
Last Post: Helge Gabert
  Joys of eBay: HP-32S, HP-32SII, HP-42S, HP-16C, ... Sasu Mattila 7 815 09-23-2013, 04:39 PM
Last Post: Julián Miranda (Spain)
  HP-16C simulator fhub 12 1,167 06-30-2013, 10:14 PM
Last Post: Robert Prosperi
  Program for HP-16c... Leonid 9 944 06-07-2013, 08:51 PM
Last Post: David Hayden
  HP 11C/12C/15C/16C case Philippe Cairic 4 737 11-06-2012, 06:04 PM
Last Post: Matt Agajanian

Forum Jump: