X-Git-Url: https://mattmccutchen.net/bigint/bigint.git/blobdiff_plain/e257a1b25b880dc6246189e7ede1d0ea3db6337d..a8b42b686243a175ea328c74609c7de6a0163274:/BigIntegerUtils.hh diff --git a/BigIntegerUtils.hh b/BigIntegerUtils.hh index 0080942..df91ef8 100644 --- a/BigIntegerUtils.hh +++ b/BigIntegerUtils.hh @@ -22,6 +22,10 @@ std::string easyBItoString(const BigInteger &x); BigUnsigned easyStringToBU(const std::string &s); BigInteger easyStringToBI(const std::string &s); +// Creates a BigInteger from data such as `char's; read below for details. +template +BigInteger easyDataToBI(const T* data, BigInteger::Index length, BigInteger::Sign sign); + // Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'. std::ostream &operator <<(std::ostream &os, const BigUnsigned &x); @@ -29,4 +33,52 @@ std::ostream &operator <<(std::ostream &os, const BigUnsigned &x); // My somewhat arbitrary policy: a negative sign comes before a base indicator (like -0xFF). std::ostream &operator <<(std::ostream &os, const BigInteger &x); +/* +* ================================= +* BELOW THIS POINT are template definitions; above are declarations. See `NumberlikeArray.hh'. +*/ + +/* +* Converts binary data to a BigInteger. +* Pass an array `data', its length, and the desired sign. +* +* Elements of `data' may be of any type `T' that has the following +* two properties (this includes almost all integral types): +* +* (1) `sizeof(T)' correctly gives the amount of binary data in one +* value of `T' and is a factor of `sizeof(Blk)'. +* +* (2) When a value of `T' is casted to a `Blk', the low bytes of +* the result contain the desired binary data. +*/ +template +BigInteger easyDataToBI(const T* data, BigInteger::Index length, BigInteger::Sign sign) { + // really ceiling(numBytes / sizeof(BigInteger::Blk)) + unsigned int pieceSizeInBits = 8 * sizeof(T); + unsigned int piecesPerBlock = sizeof(BigInteger::Blk) / sizeof(T); + unsigned int numBlocks = (length + piecesPerBlock - 1) / piecesPerBlock; + std::cout << pieceSizeInBits << ' ' << piecesPerBlock << ' ' << numBlocks << std::endl; + + // Allocate our block array + BigInteger::Blk *blocks = new BigInteger::Blk[numBlocks]; + + BigInteger::Index blockNum, pieceNum, pieceNumHere; + + // Convert + for (BigInteger::Index blockNum = 0, pieceNum = 0; blockNum < numBlocks; blockNum++) { + BigInteger::Blk curBlock = 0; + for (unsigned int pieceNumHere = 0; pieceNumHere < piecesPerBlock && pieceNum < length; + pieceNumHere++, pieceNum++) + curBlock |= (BigInteger::Blk(data[pieceNum]) << (pieceSizeInBits * pieceNumHere)); + blocks[blockNum] = curBlock; + std::cout << curBlock << std::endl; + } + + // Create the BigInteger. + BigInteger x(blocks, numBlocks, sign); + + delete blocks; + return x; +} + #endif