int128.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "int128.h"
  2. #include <tuple>
  3. IOutputStream& operator<<(IOutputStream& out, const ui128& other) {
  4. // see http://stackoverflow.com/questions/4361441/c-print-a-biginteger-in-base-10
  5. // and http://stackoverflow.com/questions/8023414/how-to-convert-a-128-bit-integer-to-a-decimal-ascii-string-in-c
  6. int d[39] = {0};
  7. int i;
  8. int j;
  9. for (i = 63; i > -1; i--) {
  10. if ((other.High_ >> i) & 1)
  11. ++d[0];
  12. for (j = 0; j < 39; j++)
  13. d[j] *= 2;
  14. for (j = 0; j < 38; j++) {
  15. d[j + 1] += d[j] / 10;
  16. d[j] %= 10;
  17. }
  18. }
  19. for (i = 63; i > -1; i--) {
  20. if ((other.Low_ >> i) & 1)
  21. ++d[0];
  22. if (i > 0)
  23. for (j = 0; j < 39; j++)
  24. d[j] *= 2;
  25. for (j = 0; j < 38; j++) {
  26. d[j + 1] += d[j] / 10;
  27. d[j] %= 10;
  28. }
  29. }
  30. for (i = 38; i > 0; i--)
  31. if (d[i] > 0)
  32. break;
  33. for (; i > -1; i--)
  34. out << static_cast<char>('0' + d[i]);
  35. return out;
  36. }
  37. void TSerializer<ui128>::Save(IOutputStream* out, const ui128& Number) {
  38. ::Save(out, GetHigh(Number));
  39. ::Save(out, GetLow(Number));
  40. }
  41. void TSerializer<ui128>::Load(IInputStream* in, ui128& Number) {
  42. ui64 High;
  43. ui64 Low;
  44. ::Load(in, High);
  45. ::Load(in, Low);
  46. Number = ui128(High, Low);
  47. }
  48. IOutputStream& operator<<(IOutputStream& out, const i128& other)
  49. {
  50. if (other >= 0) {
  51. out << ui128{other};
  52. } else {
  53. out << '-' << ui128{-other};
  54. }
  55. return out;
  56. }