1
1
//!
2
- //! Multiplication operator trait implementation
2
+ //! Subtraction operator trait implementation
3
3
//!
4
4
5
5
use crate :: * ;
@@ -19,111 +19,177 @@ impl Sub<BigDecimal> for BigDecimal {
19
19
}
20
20
21
21
let mut lhs = self ;
22
- let scale = cmp:: max ( lhs. scale , rhs. scale ) ;
23
-
24
22
match lhs. scale . cmp ( & rhs. scale ) {
25
23
Ordering :: Equal => {
26
24
lhs. int_val -= rhs. int_val ;
27
25
lhs
28
26
}
29
- Ordering :: Less => lhs. take_and_scale ( scale) - rhs,
30
- Ordering :: Greater => lhs - rhs. take_and_scale ( scale) ,
27
+ Ordering :: Less => {
28
+ lhs. take_and_scale ( rhs. scale ) - rhs
29
+ }
30
+ Ordering :: Greater => {
31
+ let rhs = rhs. take_and_scale ( lhs. scale ) ;
32
+ lhs - rhs
33
+ } ,
31
34
}
32
35
}
33
36
}
34
37
35
- impl < ' a , T : Into < BigDecimalRef < ' a > > > Sub < T > for BigDecimal {
38
+ impl Sub < BigDecimal > for & ' _ BigDecimal {
36
39
type Output = BigDecimal ;
37
40
38
41
#[ inline]
42
+ fn sub ( self , rhs : BigDecimal ) -> BigDecimal {
43
+ self . to_ref ( ) - rhs
44
+ }
45
+ }
46
+
47
+ impl Sub < BigDecimal > for BigDecimalRef < ' _ > {
48
+ type Output = BigDecimal ;
49
+
50
+ #[ inline]
51
+ fn sub ( self , rhs : BigDecimal ) -> BigDecimal {
52
+ ( rhs - self ) . neg ( )
53
+ }
54
+ }
55
+
56
+ impl < ' a , T : Into < BigDecimalRef < ' a > > > Sub < T > for BigDecimal {
57
+ type Output = BigDecimal ;
58
+
39
59
fn sub ( mut self , rhs : T ) -> BigDecimal {
40
- let rhs = rhs . into ( ) ;
41
- if rhs . is_zero ( ) {
42
- return self
43
- }
60
+ self . sub_assign ( rhs ) ;
61
+ self
62
+ }
63
+ }
44
64
45
- if self . is_zero ( ) {
46
- self . int_val = BigInt :: from_biguint ( rhs. sign . neg ( ) , rhs. digits . clone ( ) ) ;
47
- self . scale = rhs. scale ;
48
- return self
49
- }
65
+ impl < ' a , T : Into < BigDecimalRef < ' a > > > Sub < T > for & ' _ BigDecimal {
66
+ type Output = BigDecimal ;
50
67
51
- let mut lhs = self ;
52
- match lhs. scale . cmp ( & rhs. scale ) {
68
+ fn sub ( self , rhs : T ) -> BigDecimal {
69
+ let rhs = rhs. into ( ) ;
70
+
71
+ match self . scale . cmp ( & rhs. scale ) {
53
72
Ordering :: Equal => {
54
- lhs. int_val -= BigInt :: from_biguint ( rhs. sign , rhs. digits . clone ( ) ) ;
55
- lhs
73
+ self . clone ( ) - rhs
56
74
}
57
75
Ordering :: Less => {
58
- lhs . take_and_scale ( rhs. scale ) - rhs. to_owned ( )
76
+ self . with_scale ( rhs. scale ) - rhs
59
77
}
60
78
Ordering :: Greater => {
61
- lhs - rhs. to_owned_with_scale ( lhs . scale )
62
- } ,
79
+ self - rhs. to_owned_with_scale ( self . scale )
80
+ }
63
81
}
64
82
}
65
83
}
66
84
67
- impl < ' a > Sub < BigDecimal > for & ' a BigDecimal {
85
+ impl < ' a , T : Into < BigDecimalRef < ' a > > > Sub < T > for BigDecimalRef < ' _ > {
68
86
type Output = BigDecimal ;
69
87
70
- #[ inline]
71
- fn sub ( self , rhs : BigDecimal ) -> BigDecimal {
72
- -( rhs - self )
88
+ fn sub ( self , rhs : T ) -> BigDecimal {
89
+ let rhs = rhs. into ( ) ;
90
+
91
+ match self . scale . cmp ( & rhs. scale ) {
92
+ Ordering :: Equal => self . clone ( ) - rhs,
93
+ Ordering :: Less => self . to_owned_with_scale ( rhs. scale ) - rhs,
94
+ Ordering :: Greater => self - rhs. to_owned_with_scale ( self . scale ) ,
95
+ }
73
96
}
74
97
}
75
98
76
99
impl Sub < BigInt > for BigDecimal {
77
100
type Output = BigDecimal ;
78
101
102
+ fn sub ( mut self , rhs : BigInt ) -> BigDecimal {
103
+ self . sub_assign ( rhs) ;
104
+ self
105
+ }
106
+ }
107
+
108
+
109
+ impl Sub < BigInt > for & ' _ BigDecimal {
110
+ type Output = BigDecimal ;
111
+
79
112
#[ inline]
80
113
fn sub ( self , rhs : BigInt ) -> BigDecimal {
81
- if rhs . is_zero ( ) {
82
- return self ;
83
- }
114
+ self . to_ref ( ) - rhs
115
+ }
116
+ }
84
117
85
- let mut lhs = self ;
118
+ impl Sub < BigInt > for BigDecimalRef < ' _ > {
119
+ type Output = BigDecimal ;
86
120
87
- match lhs. scale . cmp ( & 0 ) {
88
- Ordering :: Equal => {
89
- lhs. int_val -= rhs;
90
- lhs
91
- }
92
- Ordering :: Greater => {
93
- lhs. int_val -= rhs * ten_to_the ( lhs. scale as u64 ) ;
94
- lhs
95
- }
96
- Ordering :: Less => lhs. take_and_scale ( 0 ) - rhs,
97
- }
121
+ #[ inline]
122
+ fn sub ( self , rhs : BigInt ) -> BigDecimal {
123
+ self - BigDecimal :: from ( rhs)
98
124
}
99
125
}
100
126
101
- impl < ' a > Sub < BigInt > for & ' a BigDecimal {
127
+ impl < ' a > Sub < BigDecimal > for BigInt {
102
128
type Output = BigDecimal ;
103
129
104
130
#[ inline]
105
- fn sub ( self , rhs : BigInt ) -> BigDecimal {
106
- BigDecimal :: new ( rhs, 0 ) - self
131
+ fn sub ( self , rhs : BigDecimal ) -> BigDecimal {
132
+ ( rhs - self ) . neg ( )
107
133
}
108
134
}
109
135
110
- impl < ' a , ' b , T : Into < BigDecimalRef < ' b > > > Sub < T > for & ' a BigDecimal {
136
+ impl < ' a > Sub < BigDecimal > for & BigInt {
111
137
type Output = BigDecimal ;
112
138
113
139
#[ inline]
114
- fn sub ( self , rhs : T ) -> BigDecimal {
115
- let rhs = rhs. into ( ) ;
140
+ fn sub ( self , rhs : BigDecimal ) -> BigDecimal {
141
+ ( rhs - self ) . neg ( )
142
+ }
143
+ }
144
+
145
+ impl < ' a > Sub < BigDecimalRef < ' a > > for BigInt {
146
+ type Output = BigDecimal ;
147
+
148
+ #[ inline]
149
+ fn sub ( self , rhs : BigDecimalRef < ' a > ) -> BigDecimal {
150
+ ( rhs - & self ) . neg ( )
151
+ }
152
+ }
153
+
154
+
155
+ impl < ' a > Sub < BigDecimalRef < ' a > > for & BigInt {
156
+ type Output = BigDecimal ;
116
157
158
+ #[ inline]
159
+ fn sub ( self , rhs : BigDecimalRef < ' a > ) -> BigDecimal {
160
+ ( rhs - self ) . neg ( )
161
+ }
162
+ }
163
+
164
+
165
+ impl SubAssign < BigDecimal > for BigDecimal {
166
+ #[ inline]
167
+ fn sub_assign ( & mut self , rhs : BigDecimal ) {
168
+ if rhs. is_zero ( ) {
169
+ return ;
170
+ }
171
+ if self . is_zero ( ) {
172
+ * self = rhs. neg ( ) ;
173
+ return ;
174
+ }
117
175
match self . scale . cmp ( & rhs. scale ) {
118
- Ordering :: Equal => self . clone ( ) - rhs,
119
- Ordering :: Less => self . with_scale ( rhs. scale ) - rhs,
120
- Ordering :: Greater => self - rhs. to_owned_with_scale ( self . scale ) ,
176
+ Ordering :: Equal => {
177
+ self . int_val -= rhs. int_val ;
178
+ }
179
+ Ordering :: Less => {
180
+ self . int_val *= ten_to_the ( ( rhs. scale - self . scale ) as u64 ) ;
181
+ self . int_val -= rhs. int_val ;
182
+ self . scale = rhs. scale ;
183
+ }
184
+ Ordering :: Greater => {
185
+ let mut rhs_int_val = rhs. int_val ;
186
+ rhs_int_val *= ten_to_the ( ( self . scale - rhs. scale ) as u64 ) ;
187
+ self . int_val -= rhs_int_val;
188
+ }
121
189
}
122
190
}
123
191
}
124
192
125
- forward_val_assignop ! ( impl SubAssign for BigDecimal , sub_assign) ;
126
-
127
193
impl < ' rhs , T : Into < BigDecimalRef < ' rhs > > > SubAssign < T > for BigDecimal {
128
194
#[ inline]
129
195
fn sub_assign ( & mut self , rhs : T ) {
@@ -169,27 +235,68 @@ mod test {
169
235
( $name: ident: $a: literal - $b: literal => $c: literal ) => {
170
236
#[ test]
171
237
fn $name( ) {
172
- let mut a: BigDecimal = $a. parse( ) . unwrap( ) ;
238
+ let a: BigDecimal = $a. parse( ) . unwrap( ) ;
173
239
let b: BigDecimal = $b. parse( ) . unwrap( ) ;
174
240
let c: BigDecimal = $c. parse( ) . unwrap( ) ;
175
241
176
- assert_eq!( a. clone( ) - b. clone( ) , c) ;
242
+ assert_eq!( c, a. clone( ) - b. clone( ) ) ;
243
+
244
+ assert_eq!( c, a. clone( ) - & b) ;
245
+ assert_eq!( c, & a - b. clone( ) ) ;
246
+ assert_eq!( c, & a - & b) ;
177
247
178
- assert_eq!( a . clone ( ) - & b, c ) ;
179
- assert_eq!( & a - b. clone ( ) , c ) ;
180
- assert_eq!( & a - & b , c ) ;
248
+ assert_eq!( c , a . to_ref ( ) - & b) ;
249
+ assert_eq!( c , & a - b. to_ref ( ) ) ;
250
+ assert_eq!( c , a . to_ref ( ) - b . to_ref ( ) ) ;
181
251
182
- a -= b;
183
- assert_eq!( a, c) ;
252
+ let mut n = a. clone( ) ;
253
+ n -= b. to_ref( ) ;
254
+ assert_eq!( n, c) ;
255
+
256
+ let mut n = a. clone( ) ;
257
+ n -= & b;
258
+ assert_eq!( n, c) ;
259
+
260
+ let mut n = a. clone( ) ;
261
+ n -= b. clone( ) ;
262
+ assert_eq!( n, c) ;
263
+
264
+ let mut n = a. clone( ) ;
265
+ ( & mut n) . sub_assign( b. clone( ) ) ;
266
+ assert_eq!( n, c) ;
267
+ }
268
+ } ;
269
+ ( $name: ident: $a: literal - ( int) $b: literal => $c: literal ) => {
270
+ #[ test]
271
+ fn $name( ) {
272
+ let a: BigDecimal = $a. parse( ) . unwrap( ) ;
273
+ let b: BigInt = $b. parse( ) . unwrap( ) ;
274
+ let expected: BigDecimal = $c. parse( ) . unwrap( ) ;
275
+
276
+ assert_eq!( expected, a. clone( ) - b. clone( ) ) ;
277
+ assert_eq!( expected, a. clone( ) - & b) ;
278
+ assert_eq!( expected, & a - & b) ;
279
+ assert_eq!( expected, & a - b. clone( ) ) ;
280
+ assert_eq!( expected, a. to_ref( ) - & b) ;
281
+
282
+ let expected_neg = expected. clone( ) . neg( ) ;
283
+ assert_eq!( expected_neg, b. clone( ) - a. clone( ) ) ;
284
+ assert_eq!( expected_neg, & b - a. to_ref( ) ) ;
285
+ assert_eq!( expected_neg, & b - a. clone( ) ) ;
184
286
}
185
287
} ;
186
288
}
187
289
188
290
impl_case ! ( case_1234en2_1234en3: "12.34" - "1.234" => "11.106" ) ;
189
291
impl_case ! ( case_1234en2_n1234en3: "12.34" - "-1.234" => "13.574" ) ;
190
292
impl_case ! ( case_1234e6_1234en6: "1234e6" - "1234e-6" => "1233999999.998766" ) ;
293
+ impl_case ! ( case_1234en6_1234e6: "1234e-6" - "1234e6" => "-1233999999.998766" ) ;
294
+ impl_case ! ( case_712911676en6_4856259269250829: "712911676e-6" - "4856259269250829" => "-4856259269250116.088324" ) ;
191
295
impl_case ! ( case_85616001e4_0: "85616001e4" - "0" => "85616001e4" ) ;
192
296
impl_case ! ( case_0_520707672en5: "0" - "5207.07672" => "-520707672e-5" ) ;
297
+ impl_case ! ( case_99291289e5_int0: "99291289e5" - ( int) "0" => "99291289e5" ) ;
298
+ impl_case ! ( case_7051277471570131en16_int1: "0.7051277471570131" - ( int) "1" => "-0.2948722528429869" ) ;
299
+ impl_case ! ( case_4068603022763836en8_intneg10: "40686030.22763836" - ( int) "-10" => "40686040.22763836" ) ;
193
300
194
301
#[ cfg( property_tests) ]
195
302
mod prop {
@@ -203,21 +310,22 @@ mod test {
203
310
// ignore non-normal numbers
204
311
prop_assume!( f. is_normal( ) ) ;
205
312
prop_assume!( g. is_normal( ) ) ;
313
+ prop_assume!( ( f. log10( ) - g. log10( ) ) . abs( ) < 100_000 ) ;
206
314
207
315
let a = BigDecimal :: from_f32( f) . unwrap( ) ;
208
316
let b = BigDecimal :: from_f32( g) . unwrap( ) ;
209
- let own_plus_ref = a. clone( ) + & b;
210
- let ref_plus_own = & a + b. clone( ) ;
317
+ let own_minus_ref = a. clone( ) - & b;
318
+ let ref_minus_own = & a - b. clone( ) ;
211
319
212
320
let mut c = a. clone( ) ;
213
- c + = & b;
321
+ c - = & b;
214
322
215
323
let mut d = a. clone( ) ;
216
- d + = b;
324
+ d - = b;
217
325
218
- prop_assert_eq!( & own_plus_ref , & ref_plus_own ) ;
219
- prop_assert_eq!( & c, & ref_plus_own ) ;
220
- prop_assert_eq!( & d, & ref_plus_own ) ;
326
+ prop_assert_eq!( & own_minus_ref , & ref_minus_own ) ;
327
+ prop_assert_eq!( & c, & ref_minus_own ) ;
328
+ prop_assert_eq!( & d, & ref_minus_own ) ;
221
329
}
222
330
223
331
#[ test]
0 commit comments