@@ -203,134 +203,6 @@ macro_rules! midpoint_impl {
203
203
} ;
204
204
}
205
205
206
- macro_rules! widening_impl {
207
- ( $SelfT: ty, $WideT: ty, $BITS: literal, unsigned) => {
208
- /// Calculates the complete product `self * rhs` without the possibility to overflow.
209
- ///
210
- /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
211
- /// of the result as two separate values, in that order.
212
- ///
213
- /// If you also need to add a carry to the wide result, then you want
214
- /// [`Self::carrying_mul`] instead.
215
- ///
216
- /// # Examples
217
- ///
218
- /// Basic usage:
219
- ///
220
- /// Please note that this example is shared between integer types.
221
- /// Which explains why `u32` is used here.
222
- ///
223
- /// ```
224
- /// #![feature(bigint_helper_methods)]
225
- /// assert_eq!(5u32.widening_mul(2), (10, 0));
226
- /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2));
227
- /// ```
228
- #[ unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
229
- #[ must_use = "this returns the result of the operation, \
230
- without modifying the original"]
231
- #[ inline]
232
- pub const fn widening_mul( self , rhs: Self ) -> ( Self , Self ) {
233
- // note: longer-term this should be done via an intrinsic,
234
- // but for now we can deal without an impl for u128/i128
235
- // SAFETY: overflow will be contained within the wider types
236
- let wide = unsafe { ( self as $WideT) . unchecked_mul( rhs as $WideT) } ;
237
- ( wide as $SelfT, ( wide >> $BITS) as $SelfT)
238
- }
239
-
240
- /// Calculates the "full multiplication" `self * rhs + carry`
241
- /// without the possibility to overflow.
242
- ///
243
- /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
244
- /// of the result as two separate values, in that order.
245
- ///
246
- /// Performs "long multiplication" which takes in an extra amount to add, and may return an
247
- /// additional amount of overflow. This allows for chaining together multiple
248
- /// multiplications to create "big integers" which represent larger values.
249
- ///
250
- /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead.
251
- ///
252
- /// # Examples
253
- ///
254
- /// Basic usage:
255
- ///
256
- /// Please note that this example is shared between integer types.
257
- /// Which explains why `u32` is used here.
258
- ///
259
- /// ```
260
- /// #![feature(bigint_helper_methods)]
261
- /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0));
262
- /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0));
263
- /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2));
264
- /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2));
265
- #[ doc = concat!( "assert_eq!(" ,
266
- stringify!( $SelfT) , "::MAX.carrying_mul(" , stringify!( $SelfT) , "::MAX, " , stringify!( $SelfT) , "::MAX), " ,
267
- "(0, " , stringify!( $SelfT) , "::MAX));"
268
- ) ]
269
- /// ```
270
- ///
271
- /// This is the core operation needed for scalar multiplication when
272
- /// implementing it for wider-than-native types.
273
- ///
274
- /// ```
275
- /// #![feature(bigint_helper_methods)]
276
- /// fn scalar_mul_eq(little_endian_digits: &mut Vec<u16>, multiplicand: u16) {
277
- /// let mut carry = 0;
278
- /// for d in little_endian_digits.iter_mut() {
279
- /// (*d, carry) = d.carrying_mul(multiplicand, carry);
280
- /// }
281
- /// if carry != 0 {
282
- /// little_endian_digits.push(carry);
283
- /// }
284
- /// }
285
- ///
286
- /// let mut v = vec![10, 20];
287
- /// scalar_mul_eq(&mut v, 3);
288
- /// assert_eq!(v, [30, 60]);
289
- ///
290
- /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D);
291
- /// let mut v = vec![0x4321, 0x8765];
292
- /// scalar_mul_eq(&mut v, 0xFEED);
293
- /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]);
294
- /// ```
295
- ///
296
- /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul),
297
- /// except that it gives the value of the overflow instead of just whether one happened:
298
- ///
299
- /// ```
300
- /// #![feature(bigint_helper_methods)]
301
- /// let r = u8::carrying_mul(7, 13, 0);
302
- /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13));
303
- /// let r = u8::carrying_mul(13, 42, 0);
304
- /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42));
305
- /// ```
306
- ///
307
- /// The value of the first field in the returned tuple matches what you'd get
308
- /// by combining the [`wrapping_mul`](Self::wrapping_mul) and
309
- /// [`wrapping_add`](Self::wrapping_add) methods:
310
- ///
311
- /// ```
312
- /// #![feature(bigint_helper_methods)]
313
- /// assert_eq!(
314
- /// 789_u16.carrying_mul(456, 123).0,
315
- /// 789_u16.wrapping_mul(456).wrapping_add(123),
316
- /// );
317
- /// ```
318
- #[ unstable( feature = "bigint_helper_methods" , issue = "85532" ) ]
319
- #[ must_use = "this returns the result of the operation, \
320
- without modifying the original"]
321
- #[ inline]
322
- pub const fn carrying_mul( self , rhs: Self , carry: Self ) -> ( Self , Self ) {
323
- // note: longer-term this should be done via an intrinsic,
324
- // but for now we can deal without an impl for u128/i128
325
- // SAFETY: overflow will be contained within the wider types
326
- let wide = unsafe {
327
- ( self as $WideT) . unchecked_mul( rhs as $WideT) . unchecked_add( carry as $WideT)
328
- } ;
329
- ( wide as $SelfT, ( wide >> $BITS) as $SelfT)
330
- }
331
- } ;
332
- }
333
-
334
206
impl i8 {
335
207
int_impl ! {
336
208
Self = i8 ,
@@ -551,7 +423,6 @@ impl u8 {
551
423
from_xe_bytes_doc = "" ,
552
424
bound_condition = "" ,
553
425
}
554
- widening_impl ! { u8 , u16 , 8 , unsigned }
555
426
midpoint_impl ! { u8 , u16 , unsigned }
556
427
557
428
/// Checks if the value is within the ASCII range.
@@ -1167,7 +1038,6 @@ impl u16 {
1167
1038
from_xe_bytes_doc = "" ,
1168
1039
bound_condition = "" ,
1169
1040
}
1170
- widening_impl ! { u16 , u32 , 16 , unsigned }
1171
1041
midpoint_impl ! { u16 , u32 , unsigned }
1172
1042
1173
1043
/// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`].
@@ -1215,7 +1085,6 @@ impl u32 {
1215
1085
from_xe_bytes_doc = "" ,
1216
1086
bound_condition = "" ,
1217
1087
}
1218
- widening_impl ! { u32 , u64 , 32 , unsigned }
1219
1088
midpoint_impl ! { u32 , u64 , unsigned }
1220
1089
}
1221
1090
@@ -1239,7 +1108,6 @@ impl u64 {
1239
1108
from_xe_bytes_doc = "" ,
1240
1109
bound_condition = "" ,
1241
1110
}
1242
- widening_impl ! { u64 , u128 , 64 , unsigned }
1243
1111
midpoint_impl ! { u64 , u128 , unsigned }
1244
1112
}
1245
1113
@@ -1289,7 +1157,6 @@ impl usize {
1289
1157
from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!( ) ,
1290
1158
bound_condition = " on 16-bit targets" ,
1291
1159
}
1292
- widening_impl ! { usize , u32 , 16 , unsigned }
1293
1160
midpoint_impl ! { usize , u32 , unsigned }
1294
1161
}
1295
1162
@@ -1314,7 +1181,6 @@ impl usize {
1314
1181
from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!( ) ,
1315
1182
bound_condition = " on 32-bit targets" ,
1316
1183
}
1317
- widening_impl ! { usize , u64 , 32 , unsigned }
1318
1184
midpoint_impl ! { usize , u64 , unsigned }
1319
1185
}
1320
1186
@@ -1339,7 +1205,6 @@ impl usize {
1339
1205
from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!( ) ,
1340
1206
bound_condition = " on 64-bit targets" ,
1341
1207
}
1342
- widening_impl ! { usize , u128 , 64 , unsigned }
1343
1208
midpoint_impl ! { usize , u128 , unsigned }
1344
1209
}
1345
1210
0 commit comments