Arbitrary precision bit manipulation (Objective C)

2019-09-19 01:14发布

问题:

I need to do bit operations on representations of arbitrary precision numbers in Objective C. So far I have been using NSData objects to hold the numbers - is there a way to bit shift the content of those? If not, is there a different way to achieve this?

回答1:

Using NSMutableData you can fetch the byte in a char, shift your bits and replace it with -replaceBytesInRange:withBytes:.

I don't see any other solution except for writing your own date holder class using a char * buffer to hold the raw data.



回答2:

As you'll have spotted, Apple doesn't provide arbitrary precision support. Nothing is provided larger than the 1024-bit integers in vecLib.

I also don't think NSData provides shifts and rolls. So you're going to have to roll your own. E.g. a very naive version, which may have some small errors as I'm typing it directly here:

@interface NSData (Shifts)

- (NSData *)dataByShiftingLeft:(NSUInteger)bitCount
{
    // we'll work byte by byte
    int wholeBytes = bitCount >> 3;
    int extraBits = bitCount&7;

    NSMutableData *newData = [NSMutableData dataWithLength:self.length + wholeBytes + (extraBits ? 1 : 0)];

    if(extraBits)
    {
        uint8_t *sourceBytes = [self bytes];
        uint8_t *destinationBytes = [newData mutableBytes];

        for(int index = 0; index < self.length-1; index++)
        {
            destinationBytes[index] =
                  (sourceBytes[index] >> (8-extraBits)) |
                  (sourceBytes[index+1] << extraBits);
        }
        destinationBytes[index] = roll >> (8-extraBits);
    }
    else 
        /* just copy all of self into the beginning of newData */

    return newData;
}

@end

Of course, that assumes the number of bits you want to shift by is itself expressible as an NSUInteger, amongst other sins.