BigIntegerUtils.hh 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #ifndef BIGINTEGERUTILS_H
  2. #define BIGINTEGERUTILS_H
  3. #include "BigInteger.hh"
  4. #include <string>
  5. #include <iostream>
  6. /* This file provides:
  7. * - Convenient std::string <-> BigUnsigned/BigInteger conversion routines
  8. * - std::ostream << operators for BigUnsigned/BigInteger */
  9. // std::string conversion routines. Base 10 only.
  10. std::string bigUnsignedToString(const BigUnsigned &x);
  11. std::string bigIntegerToString(const BigInteger &x);
  12. BigUnsigned stringToBigUnsigned(const std::string &s);
  13. BigInteger stringToBigInteger(const std::string &s);
  14. // Creates a BigInteger from data such as `char's; read below for details.
  15. template <class T>
  16. BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign);
  17. // Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'.
  18. std::ostream &operator <<(std::ostream &os, const BigUnsigned &x);
  19. // Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'.
  20. // My somewhat arbitrary policy: a negative sign comes before a base indicator (like -0xFF).
  21. std::ostream &operator <<(std::ostream &os, const BigInteger &x);
  22. // BEGIN TEMPLATE DEFINITIONS.
  23. /*
  24. * Converts binary data to a BigInteger.
  25. * Pass an array `data', its length, and the desired sign.
  26. *
  27. * Elements of `data' may be of any type `T' that has the following
  28. * two properties (this includes almost all integral types):
  29. *
  30. * (1) `sizeof(T)' correctly gives the amount of binary data in one
  31. * value of `T' and is a factor of `sizeof(Blk)'.
  32. *
  33. * (2) When a value of `T' is casted to a `Blk', the low bytes of
  34. * the result contain the desired binary data.
  35. */
  36. template <class T>
  37. BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign) {
  38. // really ceiling(numBytes / sizeof(BigInteger::Blk))
  39. unsigned int pieceSizeInBits = 8 * sizeof(T);
  40. unsigned int piecesPerBlock = sizeof(BigInteger::Blk) / sizeof(T);
  41. unsigned int numBlocks = (length + piecesPerBlock - 1) / piecesPerBlock;
  42. // Allocate our block array
  43. BigInteger::Blk *blocks = new BigInteger::Blk[numBlocks];
  44. BigInteger::Index blockNum, pieceNum, pieceNumHere;
  45. // Convert
  46. for (blockNum = 0, pieceNum = 0; blockNum < numBlocks; blockNum++) {
  47. BigInteger::Blk curBlock = 0;
  48. for (pieceNumHere = 0; pieceNumHere < piecesPerBlock && pieceNum < length;
  49. pieceNumHere++, pieceNum++)
  50. curBlock |= (BigInteger::Blk(data[pieceNum]) << (pieceSizeInBits * pieceNumHere));
  51. blocks[blockNum] = curBlock;
  52. }
  53. // Create the BigInteger.
  54. BigInteger x(blocks, numBlocks, sign);
  55. delete [] blocks;
  56. return x;
  57. }
  58. #endif