Shop OBEX P1 Docs P2 Docs Learn Events
How many characters needed to display X numbers of longs decimal — Parallax Forums

How many characters needed to display X numbers of longs decimal

I am trying to display a given buffer of longs (say 1 to 1000) as one decimal number over serial. So I have to output the leftmost decimal character first.
I already can do that in HEX, it is way more easy there.

So what I need, is a way to figure out how much decimal places are needed for the biggest needed divisor.

Take PST as example:
PRI Dec(value) | i, x

  x := value == NEGX                                    'Check for max negative
  if value < 0
    value := ||(value+x)                                'If negative, make positive; adjust for max negative
    ser.Tx("-")                                         'and output sign

 [b] i := 1_000_000_000                                    'Initialize divisor[/b]

  repeat 10                                             'Loop for 10 digits
    if value => i                                                               
      ser.Tx(value / i + "0" + x*(i == 1))              'If non-zero digit, output digit; adjust for max negative
      value //= i                                       'and digit from value
      result~~                                          'flag non-zero found
    elseif result or i == 1
      ser.Tx("0")                                       'If zero digit (or only digit) output it
    i /= 10                                             'Update divisor

Or, to be precise, I need a way to calculate that biggest needed divisor itself, not just the number of digits, but that would be ok also.

for 1 long it is 10 digits - 1_000_000_000
for 2 longs it is 19 digits - 1_000_000_000_000_000_000
...
for x longs it is ?

how does this progress, and why?

Is there any trick to calculate the needed digits, instead of multiplying 1 by ten until my number runs out of longs and sets a carry flag?

curious,

Mike

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2017-08-30 00:33
    In Forth we build the string backwards from least significant digit just by dividing by the base until we end up with zero.
    ..  12345678 <# #S #> $10 DUMP 
    0000.016D:  31 32 33  34 35 36 37  38 00 11 00  00 00 00 00  00    12345678........
    ..  123 <# #S #> $10 DUMP 
    0000.0172:  31 32  33 00 16 00  00 00 00 00  00 00 00 00  00 00    123.............
    

    btw, we can also print out 64-bit numbers too.
    ..  1,000,000,000 123,000,000 UM*  
    ..  .S  Data Stack (2)
    $01B4.FBD9 - 28638169
    $2B5F.8000 - 727678976
    ..  <D> <# #S #> $20 DUMP 
    0000.0163:  31  32 33 30 30  30 30 30 30  30 30 30 30  30 30 30    1230000000000000
    0000.0173:  30  30 00 07 00  00 00 00 00  00 00 00 00  00 00 00    00..............
    
  • @Peter, I know, that one is easy.

    But I try to do that with my BigInts, so the memory needed to buffer a entire Number of characters is just not there.

    That is why I mentioned I need to output the leftmost digit first.

    I guess I try brute force first, and multiply my divisor by ten until I exceed the numbers of longs asked for or the divisor is bigger then the number to be outputted!.

    that should work.

    Mike

  • The thing is that this method always gives you the number of digits required. If you don't buffer them and just count them then you have your "number of characters" required.
  • jmgjmg Posts: 15,173
    msrobots wrote: »
    for 1 long it is 10 digits - 1_000_000_000
    for 2 longs it is 19 digits - 1_000_000_000_000_000_000
    ...
    for x longs it is ?

    how does this progress, and why?

    Is there any trick to calculate the needed digits, instead of multiplying 1 by ten until my number runs out of longs and sets a carry flag?

    not sure what you are asking here, but isn't this just log2:log10 as in
    log(2^32) = 9.632
    log(2^64) = 19.265
    etc

  • Oh @jmg, that's a wonderful idea.

    sadly by now I can not do a log(2^32000), what I would need for my current longest Int on a P1.

    But I like the way you think.

    Mike



  • jmgjmg Posts: 15,173
    msrobots wrote: »
    sadly by now I can not do a log(2^32000), what I would need for my current longest Int on a P1.

    but log2:log10 is a fixed 0.30102999566 Digits per binary-bit, if you know the Binary bits, you can derive the decimal digits, and then round-up to nearest whole number.
    (+1 if you need sign)

Sign In or Register to comment.