sub.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. use int::LargeInt;
  2. trait Sub: LargeInt {
  3. fn sub(self, other: Self) -> Self {
  4. let neg_other = (!other).wrapping_add(Self::ONE);
  5. self.wrapping_add(neg_other)
  6. }
  7. }
  8. impl Sub for i128 {}
  9. impl Sub for u128 {}
  10. trait Subo: Sub {
  11. fn subo(self, other: Self, overflow: &mut i32) -> Self {
  12. *overflow = 0;
  13. let result = Sub::sub(self, other);
  14. if other >= Self::ZERO {
  15. if result > self {
  16. *overflow = 1;
  17. }
  18. } else {
  19. if result <= self {
  20. *overflow = 1;
  21. }
  22. }
  23. result
  24. }
  25. }
  26. impl Subo for i128 {}
  27. impl Subo for u128 {}
  28. #[cfg_attr(not(stage0), lang = "i128_sub")]
  29. pub fn rust_i128_sub(a: i128, b: i128) -> i128 {
  30. rust_u128_sub(a as _, b as _) as _
  31. }
  32. #[cfg_attr(not(stage0), lang = "i128_subo")]
  33. pub fn rust_i128_subo(a: i128, b: i128) -> (i128, bool) {
  34. let mut oflow = 0;
  35. let r = a.subo(b, &mut oflow);
  36. (r, oflow != 0)
  37. }
  38. #[cfg_attr(not(stage0), lang = "u128_sub")]
  39. pub fn rust_u128_sub(a: u128, b: u128) -> u128 {
  40. a.sub(b)
  41. }
  42. #[cfg_attr(not(stage0), lang = "u128_subo")]
  43. pub fn rust_u128_subo(a: u128, b: u128) -> (u128, bool) {
  44. let mut oflow = 0;
  45. let r = a.subo(b, &mut oflow);
  46. (r, oflow != 0)
  47. }
  48. #[test]
  49. fn test_sub() {
  50. assert_eq!(rust_u128_sub(3, 2), 1);
  51. assert_eq!(rust_u128_sub(2, 3), !0);
  52. assert_eq!(rust_u128_sub(1 << 64, 1 << 63), 1 << 63);
  53. assert_eq!(rust_u128_sub(
  54. 0xB41A6A66596687B1_3B1C743CE9F12161_u128,
  55. 0x6019CEECA5354210_839AB51D155FF7F3_u128),
  56. 0x54009B79B43145A0_B781BF1FD491296E_u128);
  57. assert_eq!(rust_u128_sub(
  58. 0x2AC60FFECA228F12_37A550530BE8B83E_u128,
  59. 0xEFDD73C41D344744_B0842900C3352A63_u128),
  60. 0x3AE89C3AACEE47CD_8721275248B38DDB_u128);
  61. assert_eq!(rust_i128_sub(3, 2), 1);
  62. assert_eq!(rust_i128_sub(2, 3), -1);
  63. }
  64. #[test]
  65. fn test_subo() {
  66. assert_eq!(rust_u128_subo(3, 2), (1, false));
  67. assert_eq!(rust_u128_subo(2, 3), (!0, true));
  68. assert_eq!(rust_u128_subo(1 << 64, 1 << 63), (1 << 63, false));
  69. assert_eq!(rust_u128_subo(
  70. 0xB41A6A66596687B1_3B1C743CE9F12161_u128,
  71. 0x6019CEECA5354210_839AB51D155FF7F3_u128),
  72. (0x54009B79B43145A0_B781BF1FD491296E_u128, false));
  73. assert_eq!(rust_u128_subo(
  74. 0x2AC60FFECA228F12_37A550530BE8B83E_u128,
  75. 0xEFDD73C41D344744_B0842900C3352A63_u128),
  76. (0x3AE89C3AACEE47CD_8721275248B38DDB_u128, true));
  77. assert_eq!(rust_i128_subo(3, 2), (1, false));
  78. assert_eq!(rust_i128_subo(2, 3), (-1, false));
  79. assert_eq!(rust_i128_subo(1 << 64, 1 << 63), (1 << 63, false));
  80. assert_eq!(rust_i128_subo(
  81. -0x4BE59599A699784E_C4E38BC3160EDE9F_i128,
  82. 0x6019CEECA5354210_839AB51D155FF7F3_i128),
  83. (0x54009B79B43145A0_B781BF1FD491296E_i128, true));
  84. assert_eq!(rust_i128_subo(
  85. 0x2AC60FFECA228F12_37A550530BE8B83E_i128,
  86. -0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128),
  87. (0x3AE89C3AACEE47CD_8721275248B38DDB_i128, false));
  88. assert_eq!(rust_i128_subo(
  89. 0x4BE59599A699784E_C4E38BC3160EDE9F_i128,
  90. -0x6019CEECA5354210_839AB51D155FF7F3_i128),
  91. (-0x54009B79B43145A0_B781BF1FD491296E_i128, true));
  92. assert_eq!(rust_i128_subo(
  93. -0x2AC60FFECA228F12_37A550530BE8B83E_i128,
  94. 0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128),
  95. (-0x3AE89C3AACEE47CD_8721275248B38DDB_i128, false));
  96. }