[chbot] int > ascii > int

Bevin Brett bevin_brett at hotmail.com
Sun Oct 25 02:00:55 GMT 2020


Ok, assuming you are NOT going to use some standard library, here are the issues and some code

Let us first discuss getting the character string from one machine to the other.
Either (a) it is fixed length,  or (b) you put a size on the beginning, or (c) you put a flag at the end
Fixed length is easiest, and least efficient.
Size is only best if the length is very long - its not going to be here.
So instead we need a flag at the end.  Lets do that - we will discuss how in a minute.

So assuming that the characters arrive one at a time you get some receiver code that  looks like

    int i = 0;
    while  (getNextChar(&c)) {
       adjust i using c
    }

Next problem.  What characters can you send.   Can you send ANY (0x00..0xff) character, or does the h/w and s/e connecting the two ends stop you from using NUL (0x00)?  CR? LF? Ctrl-S? Ctrl-Q?  others?.    Let's assume that you can only send printable chars ' '..'~'.

   char firstSendableChar = ' ';
   char lastSendableChar = '~';
   int nSendableChars = ((int)(lastSendableChar) - (int)(lastSendableChar)) + 1;

Now the basic idea, we are going to have to improve it, is to do this at the transmitting end

   int val = <the number to send>

   while (val > 0) {
       char toSend = val % nSendableChars;      // these two lines are the crux of the solution
       val                 = val / nSendableChars;
       send((char)(toSend + firstSendableChar ))
   }


  int i = 0;
  while  (getNextChar(&c)) {
       i = i*nSendableChars + (c - firstSendableChar);
  }

Okay, so now we only have two problems.  (a) negative numbers, and (b) knowing when to stop.

You could just do the above using unsigned int, and use
    unsigned int unsignedIntermediate = (unsigned int)(input);
    ...
   send and receive
   ...
    int output = (int) unsignedIntermediate;
and the only problem with that is -small is a very long this way.

A better approach is to send the sign bit similarly to sending the count.

The second problem is that there is no positive number corresponding to the most negative number, so you can't just do
    int sign = (value > 0);
    if (sign) value = -value;
Instead you have to do
    if (!sign) value = -value;

Now the above loop using % and / requires understanding how those operations work with -ve numbers.

How to send the sign and end-of-number bits?  One thing to do place them both in the last character.  To do this,
reduce the

  int nDigitChars = nSendableChars / 2;

Now we can code the above loop

 while (val > 0) {
       int    nextVal = val / nDigitChars ;
       char toSend = val % nDigitChars ;      // these two lines are the crux of the solution
       if (nextVal == 0) toSend += nDigitChars ;
       val                 = nextVal ;
       send((char)(toSend + firstSendableChar ))
   }

and the receive loop

  int i = 0;
  while  (getNextChar(&c)) {
       int atEnd = (c >= nDigitChars );
       if (atEnd) c -= nDigitChars ;
       i = i*nDigitChars + (c - firstSendableChar);
       if (atEnd) break;
  }

I'll leave it as an exercise to the reader to place the sign bit in the last sent character.

I'm not sure the complexity of the above is worth it.

Those % and / are expensive.  There are faster ways than the above - I spent a few months working on the integer to/from string in the 1990's because believe it or not it is an important operation in telephone systems.

/Bevin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ourshack.com/pipermail/chchrobotics/attachments/20201025/a75132ba/attachment-0001.html>


More information about the Chchrobotics mailing list