Shop OBEX P1 Docs P2 Docs Learn Events
how can I display a 64 bit number (2 longs) as decimal — Parallax Forums

how can I display a 64 bit number (2 longs) as decimal

phishguyphishguy Posts: 36
edited 2009-09-11 01:25 in Propeller 1
I am working on software to decode a RFID chip that has a 64 bit ID. I know that it will be easy to display the hexadecimal value. However, I need to be able to display it as decimal. I actually only need the least significant 37 bits. How would I go about doing this?
·

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-10 15:13
    You need to write a multiple precision divide by 10 routine that produces a dividend and remainder. It's really easy if you divide up the number into 24 bit pieces like this:
    var
       long dividend[noparse][[/noparse] 2 ]
       byte buffer[noparse][[/noparse] 25 ]
    
    pub convert | i
       ' return the starting address of a string with the decimal value
       result := @buffer[noparse][[/noparse]24]
       byte[noparse][[/noparse]result]~
       repeat
          byte[noparse][[/noparse]--result] := divBy10 + "0"
       while dividend[noparse][[/noparse] 0 ] or dividend[noparse][[/noparse] 1 ]
    
    pri divBy10 | i, temp
       result := 0
       repeat i from 1 to 0
          temp := (result << 24) | dividend[noparse][[/noparse] i ]
          result := temp // 10
          dividend[noparse][[/noparse] i ] := temp / 10
    
  • phishguyphishguy Posts: 36
    edited 2009-09-10 15:19
    That was quick. Thanks a bunch.
  • phishguyphishguy Posts: 36
    edited 2009-09-10 17:15
    OK, forgive me for being dense and a noob. But, I can't figure out how to use that function. Could you show me an example using VGA_TEXT for output and an input example of $0000001B· $F21B02CA ?
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-10 17:27
    You'd set "dividend[noparse][[/noparse] 1 ] := $001BF2" and "dividend[noparse][[/noparse] 0 ] := $1B02CA", then you'd call "vga.str(convert)" (assuming that "vga" is the object name of "VGA_TEXT").
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-09-10 17:29
    You can't break it up into a byte output? "0F04029599" this is an 80-bit RFID value of one of my cards. With the cards I am using all the bytes are within displayable-byte-values that look like a hex value (0..9 or A..F). I think this is a very common way to input/output values, it's fast (enough), easy to read, and easy to input.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!
  • phishguyphishguy Posts: 36
    edited 2009-09-10 17:41
    OK, that sorta works. I get 20025973450 as a result when I should get 120025973450.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-10 17:54
    I don't understand why it doesn't produce the leftmost digit. It should output all the digits until the dividend is zero with a minimum of 1 digit.
  • phishguyphishguy Posts: 36
    edited 2009-09-10 21:33
    OK, I figured out how to get the first digit. Now I have a problem where I get 16 leading spaces when I send it to the screen.
    ''***************************************
    ''*  VGA Text Demo v1.0                 *
    ''*  Author: Chip Gracey                *
    ''*  Copyright (c) 2006 Parallax, Inc.  *
    ''*  See end of file for terms of use.  *
    ''***************************************
    

    CON
    

      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    

    OBJ
    

      text : "vga_text"
      
    Var
       long dividend[noparse][[/noparse] 2 ]
       byte buffer[noparse][[/noparse] 13 ]
    

    PUB start | i
         
        dividend[noparse][[/noparse]1] := $1BF2
        dividend[noparse][[/noparse]0] := $1B02CA
         
      'start term
      text.start(16)
      text.str(string("12345678901234567890",13,10))
      
      text.str(convert)
      
     
    pub convert | i
       ' return the starting address of a string with the decimal value
       result := @buffer[noparse][[/noparse]12]
       byte[noparse][[/noparse]result]~
       repeat
          byte[noparse][[/noparse]--result] := divBy10 + "0"
       while dividend[noparse][[/noparse] 0 ] or dividend[noparse][[/noparse] 1 ]  
      byte[noparse][[/noparse]--result] := divBy10 + "0"
    

    pri divBy10 | i, temp
       result := 0
       repeat i from 1 to 0
          temp := (result << 24) | dividend[noparse][[/noparse] i ]
          result := temp // 10
          dividend[noparse][[/noparse] i ] := temp / 10
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-09-10 22:09
    phishguy,

    I ran your program using tv_text instead of vga_text and didn't see any leading spaces. I also eliminated your extra byte[noparse][[/noparse]--result] := divBy10 + "0", since it was giving me a leading zero.

    -Phil
  • TimmooreTimmoore Posts: 1,031
    edited 2009-09-10 22:11
    I tried it with a serial port and got the same results as Phil
  • phishguyphishguy Posts: 36
    edited 2009-09-10 23:41
    weird! Why am I getting different results? Maybe it has something to do with VGA_text.
  • TimmooreTimmoore Posts: 1,031
    edited 2009-09-10 23:48
    dec 10 is special to the vga text, try removing this from the end of your first string, i.e.

    text.str(string("12345678901234567890",13))
  • phishguyphishguy Posts: 36
    edited 2009-09-10 23:56
    Doh! You're right. That bit me before and I completely forgot about it.

    Thanks! All is well now.
  • VIRANDVIRAND Posts: 656
    edited 2009-09-11 01:25
    There was a simple algorithm that requires only decimal addition I think it goes like this (pseudo code).

    n = binary number to convert to decimal string

    dec2add:="1",0 'NOT VALID SPIN set one decimal string to 1
    str:="0",0 'NOT VALID SPIN set output decimal string to 0
    repeat until n==0
    if n&1 = 1
    _adddec (str, dec2add) 'NOT VALID SPIN str := str+dec2add
    n=n/2 'divide by 2
    adddec (dec2add,dec2add) 'NOT VALID SPIN dec2add := dec2add x 2

    Adddec would be a simple chalkboard addition of the second string to the first.
    I tried to describe it more but I made it sound too complicated.
Sign In or Register to comment.