add.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use int::LargeInt;
  2. use int::Int;
  3. trait UAdd: LargeInt {
  4. fn uadd(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 UAdd for u128 {}
  12. trait Add: Int
  13. where <Self as Int>::UnsignedInt: UAdd
  14. {
  15. fn add(self, other: Self) -> Self {
  16. Self::from_unsigned(self.unsigned().uadd(other.unsigned()))
  17. }
  18. }
  19. impl Add for u128 {}
  20. impl Add for i128 {}
  21. trait Addo: Add
  22. where <Self as Int>::UnsignedInt: UAdd
  23. {
  24. fn addo(self, other: Self, overflow: &mut i32) -> Self {
  25. *overflow = 0;
  26. let result = Add::add(self, other);
  27. if other >= Self::ZERO {
  28. if result < self {
  29. *overflow = 1;
  30. }
  31. } else {
  32. if result >= self {
  33. *overflow = 1;
  34. }
  35. }
  36. result
  37. }
  38. }
  39. impl Addo for i128 {}
  40. impl Addo for u128 {}
  41. #[cfg_attr(not(stage0), lang = "i128_add")]
  42. pub fn rust_i128_add(a: i128, b: i128) -> i128 {
  43. rust_u128_add(a as _, b as _) as _
  44. }
  45. #[cfg_attr(not(stage0), lang = "i128_addo")]
  46. pub fn rust_i128_addo(a: i128, b: i128) -> (i128, bool) {
  47. let mut oflow = 0;
  48. let r = a.addo(b, &mut oflow);
  49. (r, oflow != 0)
  50. }
  51. #[cfg_attr(not(stage0), lang = "u128_add")]
  52. pub fn rust_u128_add(a: u128, b: u128) -> u128 {
  53. a.add(b)
  54. }
  55. #[cfg_attr(not(stage0), lang = "u128_addo")]
  56. pub fn rust_u128_addo(a: u128, b: u128) -> (u128, bool) {
  57. let mut oflow = 0;
  58. let r = a.addo(b, &mut oflow);
  59. (r, oflow != 0)
  60. }