add.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. use int::LargeInt;
  2. use int::Int;
  3. trait Add: LargeInt {
  4. fn add(self, other: Self) -> Self {
  5. let (low, carry) = self.low().overflowing_add(other.low());
  6. let high = self.high().wrapping_add(other.high());
  7. let carry = if carry { Self::HighHalf::ONE } else { Self::HighHalf::ZERO };
  8. Self::from_parts(low, high.wrapping_add(carry))
  9. }
  10. }
  11. impl Add for u128 {}
  12. trait Addo: Int {
  13. fn addo(self, other: Self, overflow: &mut i32) -> Self {
  14. *overflow = 0;
  15. let result = self.wrapping_add(other);
  16. if other >= Self::ZERO {
  17. if result < self {
  18. *overflow = 1;
  19. }
  20. } else {
  21. if result >= self {
  22. *overflow = 1;
  23. }
  24. }
  25. result
  26. }
  27. }
  28. impl Addo for i128 {}
  29. impl Addo for u128 {}
  30. #[cfg_attr(not(stage0), lang = "i128_add")]
  31. #[allow(dead_code)]
  32. fn rust_i128_add(a: i128, b: i128) -> i128 {
  33. rust_u128_add(a as _, b as _) as _
  34. }
  35. #[cfg_attr(not(stage0), lang = "i128_addo")]
  36. #[allow(dead_code)]
  37. fn rust_i128_addo(a: i128, b: i128) -> (i128, bool) {
  38. let mut oflow = 0;
  39. let r = a.addo(b, &mut oflow);
  40. (r, oflow != 0)
  41. }
  42. #[cfg_attr(not(stage0), lang = "u128_add")]
  43. #[allow(dead_code)]
  44. fn rust_u128_add(a: u128, b: u128) -> u128 {
  45. a.add(b)
  46. }
  47. #[cfg_attr(not(stage0), lang = "u128_addo")]
  48. #[allow(dead_code)]
  49. fn rust_u128_addo(a: u128, b: u128) -> (u128, bool) {
  50. let mut oflow = 0;
  51. let r = a.addo(b, &mut oflow);
  52. (r, oflow != 0)
  53. }
  54. #[test]
  55. fn test_add() {
  56. assert_eq!(rust_u128_add(1, 2), 3);
  57. assert_eq!(rust_u128_add(!0, 3), 2);
  58. assert_eq!(rust_u128_add(1 << 63, 1 << 63), 1 << 64);
  59. assert_eq!(rust_u128_add(
  60. 0x54009B79B43145A0_B781BF1FD491296E_u128,
  61. 0x6019CEECA5354210_839AB51D155FF7F3_u128),
  62. 0xB41A6A66596687B1_3B1C743CE9F12161_u128);
  63. assert_eq!(rust_u128_add(
  64. 0x3AE89C3AACEE47CD_8721275248B38DDB_u128,
  65. 0xEFDD73C41D344744_B0842900C3352A63_u128),
  66. 0x2AC60FFECA228F12_37A550530BE8B83E_u128);
  67. assert_eq!(rust_i128_add(1, 2), 3);
  68. assert_eq!(rust_i128_add(-1, 3), 2);
  69. }
  70. #[test]
  71. fn test_addo() {
  72. assert_eq!(rust_u128_addo(1, 2), (3, false));
  73. assert_eq!(rust_u128_addo(!0, 3), (2, true));
  74. assert_eq!(rust_u128_addo(1 << 63, 1 << 63), (1 << 64, false));
  75. assert_eq!(rust_u128_addo(
  76. 0x54009B79B43145A0_B781BF1FD491296E_u128,
  77. 0x6019CEECA5354210_839AB51D155FF7F3_u128),
  78. (0xB41A6A66596687B1_3B1C743CE9F12161_u128, false));
  79. assert_eq!(rust_u128_addo(
  80. 0x3AE89C3AACEE47CD_8721275248B38DDB_u128,
  81. 0xEFDD73C41D344744_B0842900C3352A63_u128),
  82. (0x2AC60FFECA228F12_37A550530BE8B83E_u128, true));
  83. assert_eq!(rust_i128_addo(1, 2), (3, false));
  84. assert_eq!(rust_i128_addo(-1, 3), (2, false));
  85. assert_eq!(rust_i128_addo(1 << 63, 1 << 63), (1 << 64, false));
  86. assert_eq!(rust_i128_addo(
  87. 0x54009B79B43145A0_B781BF1FD491296E_i128,
  88. 0x6019CEECA5354210_839AB51D155FF7F3_i128),
  89. (-0x4BE59599A699784E_C4E38BC3160EDE9F_i128, true));
  90. assert_eq!(rust_i128_addo(
  91. 0x3AE89C3AACEE47CD_8721275248B38DDB_i128,
  92. -0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128),
  93. (0x2AC60FFECA228F12_37A550530BE8B83E_i128, false));
  94. assert_eq!(rust_i128_addo(
  95. -0x54009B79B43145A0_B781BF1FD491296E_i128,
  96. -0x6019CEECA5354210_839AB51D155FF7F3_i128),
  97. (0x4BE59599A699784E_C4E38BC3160EDE9F_i128, true));
  98. assert_eq!(rust_i128_addo(
  99. -0x3AE89C3AACEE47CD_8721275248B38DDB_i128,
  100. 0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128),
  101. (-0x2AC60FFECA228F12_37A550530BE8B83E_i128, false));
  102. }