Shop OBEX P1 Docs P2 Docs Learn Events
Decimal strings with decimal point??? — Parallax Forums

Decimal strings with decimal point???

laser-vectorlaser-vector Posts: 118
edited 2010-08-13 21:26 in Propeller 1
if i have a decimal number that is lets say "246" and i want to divide it by 10 how would i make it display as "24.6"
CON

        _clkmode = xtal1 + pll16x
        _xinfreq = 6_250_000

        {ADC I/O Configuration}
        Dpin      = 0 'pin connected to both DIN and DOUT on MCP3208
        Cpin      = 1 'pin connected to CLK on MCP3208
        Spin      = 2 'pin connected to CS  on MCP3208
        Mode      = 0 'not used, included for compatability reasons

        {Serial Configuration}
        pin       = 22
        baud      = 19200
        lines     = 4

        {LM35 Calibration}
        Scale     = 10
        Offset1   = 0
        Offset2   = 0
        Offset3   = 0
        Offset4   = 0
        
OBJ

        AD  : "MCP3208_fast"
        LCD : "Serial_Lcd"
        NUM : "Numbers"
        
PUB init

        {initilize all objects}
        AD.start(dpin, cpin, spin, mode)
        LCD.Init(pin, baud, lines)
        NUM.Init

        {clear LCD Display, turn on Backlight and turn off cursor}        
        LCD.backlight(1)        ' Enable (true) or disable (false) LCD backlight 
        LCD.cls                 ' Clears LCD and moves cursor to home (0, 0) position
        LCD.putc($16)           ' LCD on; cursor off, blink off 

        {jump to main method}
        main
    
PUB main
      repeat
        waitcnt(10_000_000 + cnt)
        LCD.CLS
        LCD.putc($80)
        LCD.str(string("CH1:"))
        LCD.str(NUM.tostr((AD.average(0, 16) / scale), num#dec))  ' this is where i need it to produce a decimal point
        LCD.str(string(" "))
        LCD.putc($94)
        LCD.str(string("CH2:")) 
        LCD.str(NUM.tostr(AD.average(1, 16), num#dec))
        LCD.str(string(" "))
        LCD.putc($A8)

Comments

  • Invent-O-DocInvent-O-Doc Posts: 768
    edited 2010-08-13 19:32
    This is how I would do it.

    Take '246' put it in variable (a for example)
    a = a / 10 ' a = 24
    a = a * 10 ' a = 240 (strips the last digit)
    b= 246 - a ' Then take '246' and subtract a, leaving just six - b will = 6
    a = a / 10 ' again - a will be 24
    then, convert to strings and concatenate a + "." + b 'so "24" + "." + "6" = "24.6"

    You will need to make a string concatenation routine or use an OBEX string library or you could use LCD driver conversion functions and spit it out to the LCD in 3 steps

    I hope this helps - someone who is more expert might have a more mathematically elegant solution.
  • localrogerlocalroger Posts: 3,452
    edited 2010-08-13 19:55
    This isn't one of those things that's real obvious. I've solved it on several different platforms including the Prop, and somewhere I have a PUB OUTDEC(val, len, dp) which allows you to stick a period in there. It works by formatting the output space first, laying out spaces and the decimal point according to the format; then it lays the digits out in reverse order. It also has to keep going until it finds the decimal point if there is one and the number is a fraction. I've checked and I don't have it on any of my media at home; if no one has gotten you a solution by Monday when I get to work I'll post it here.
  • tonyp12tonyp12 Posts: 1,951
    edited 2010-08-13 20:36
    Do you always divide by 10?

    If so convert the number to a string.
    put a decimal point before the last letter and you just divided by ten
    Something like this psedo code (I never touched spin)

    @mynumber := NUM.tostr((AD.average(0, 16) / scale), num#dec)
    move byte mynumber+strsize(@mynumber) to byte mynumber+strsize(@mynumber)+1 ' move the last letter one space over.
    move byte "." to mynumber+strsize(@mynumber) ' put a dot there instead.
    move byte 0 to mynumber+strsize(@mynumber)+2 ' put a zero just in case.

    DAT
    mynumber byte res 20
  • AribaAriba Posts: 2,690
    edited 2010-08-13 21:26
    You can do it with Division and Modulo (remainder of divison) with a decimal point in between.
    If scale is more then 10, you need the right formating constant for num.toStr: dec2 for 100, dec3 for 1000 ...
    If you use this at several position in the code, its best to make a methode for it.
    PUB main | tmp
      ...
            LCD.str(string("CH1:"))
            tmp := AD.average(0, 16)
            LCD.str(NUM.tostr(tmp / 10), num#dec))  'integer part scale=10
            LCD.str(string("."))
            LCD.str(NUM.tostr(tmp // 10), num#dec))  'decimal places (1)
      ...
            LCD.str(string("CH2:"))
            tmp := AD.average(1, 16)
            LCD.str(NUM.tostr(tmp / 100), num#dec))  'integer part scale=100
            LCD.putc(".")
            LCD.str(NUM.tostr(tmp // 100), num#dec2))  'decimal places (2)
      ...
    

    Andy
Sign In or Register to comment.