0
votes

I have a char array:

char message[];

And an 8-bit integer

uint8_t remainder

I want to treat both just as arrays of bits and subtract them like:

message - remainder

and treat the result as a char array:

An example would be

char* message = "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ";
// Equivalent to a 512-bit array of only 1s

uint8_t remainder = 1;
// Substract here message-remainder

printf("%s", message)
// Output: "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ"
// As the 512 bit array would still be just 1s except for the first bit which now is 0, so the first char would be 254 instead of 255

Is there a possible way to do it? I thought about converting the char array to an int but the problem is that it usually is a 64 byte array, so I cannot treat is an int. I think the approach goes around using bitwise operators but I haven't figured how to subtract them yet.

Any suggestions?

2
It might help people answer if you add an example to your question (an example array of characters, remainder, and what you want returned at the end out of that example). Also, you said "64 byte" array - I just wanted to make sure you mean 64 bytes and not 64 bits.thisisbenmanley
So you want to treat message as a "large" integer? BigNum libraries can do this for you. Otherwise, you subtract the first char and then subtract with carry across each remaining char. Easier done in asm, but can be done in C with help.Michael Dorgan
You don't have to do it by char either, you could do it per "word" as long as you are careful not to read outside your message array. (convert 8-characters to 64-bit integer - endian beware, if remainder is smaller than integer subtract remainder and done. If bigger, subtract, then convert next 8-bytes to integer and propogate carry. Continue until no carry or out of chars to convert)Michael Dorgan
@thisisbenmanley added and example, and yes I mean 64 byte.Nicolas Quiroz
First time, loop, if remainder <= integer, no carry and done. Else, read next word and set remainder to 1 (the carry) and Loop . End loop when out of characters to read (or when done from no carry.) Store result into either an integer array or into a typecasted byte array (beware endian). If you can guarantee the char array read in is at least "word" size and a multiple of word in length, the loop is very simple. If not, you have to handle edge cases or do it bytes/chars at a time.Michael Dorgan

2 Answers

2
votes

As requested:

  1. Read from the byte array (chars) as a type-casted integer. Beware that endian may cause this to not work correctly on some systems and you may have to endian swap. Also beware that if the data is not aligned to word boundaries, some systems may crash.
  2. Compare your remainder vs the integer. If integer >= remainder, there is no carry and you can just subtract the values and typecast store the integer back into the char array. Same exceptions apply as stated above.
  3. If remainder is bigger, still do the subtract and store, but then place a 1 into remainder.
  4. Loop back to 1, reading in next word until you exit because of no carry to propagate or out of words to read.

If data is non-aligned, not size of word, etc., you may need to do this per byte instead, but you have stated this is not the case.

Enjoy.

(Note: Using a BigNum type library is highly recommended over doing it yourself. Someday, this code may need to be ported, and this method is highly likely to break when that occurs...)

1
votes

Firstly it is generally a bad idea to do so :-( (usually cause some buffer overflow)

Secondly, since your integer of interest is a 8-bit one, it is the same size of a single char. Therefore if you do want to implement that, just do this:

if (message[strlen(message)-1]<integer){
    for (int i=strlen(message);i>0;i--){
        if (message[i-1]){
            message[i-1]--;
            for (j=i+1;j<strlen(message)-1;j++){
                message[j]=255;
            }
            message[strlen(message)-1]=(char)((int)(message[strlen(message)-1])+255-remainder);
            break;
        }
    }
    /* ERROR - message is less than remainder */
}
else{
    message[strlen(message)-1]-=remainder;
}

and you are done.

Notice that the part (char)((int)(message[strlen(message)-1])+255-remainder) may not be necessary; I am writing it just to make sure that when performing the addition and subtraction, everything is casted into int.