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