[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