@@ -2160,6 +2160,117 @@ assert_eq!((-a).rem_euclid(-b), 1);
2160
2160
}
2161
2161
}
2162
2162
2163
+ doc_comment! {
2164
+ concat!( "Returns the logarithm of the number with respect to an arbitrary base.
2165
+
2166
+ Returns `None` if the number is zero, or if the base is zero or one.
2167
+
2168
+ This method may not be optimized owing to implementation details;
2169
+ `self.checked_log2()` can produce results more efficiently for base 2, and
2170
+ `self.checked_log10()` can produce results more efficiently for base 10.
2171
+
2172
+ # Examples
2173
+
2174
+ ```
2175
+ #![feature(int_log)]
2176
+
2177
+ let five = 5" , stringify!( $SelfT) , ";
2178
+
2179
+ // log5(5) == 1
2180
+ let result = five.checked_log(5);
2181
+
2182
+ assert_eq!(result, Some(1));
2183
+ ```" ) ,
2184
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
2185
+ #[ must_use = "this returns the result of the operation, \
2186
+ without modifying the original"]
2187
+ #[ inline]
2188
+ pub fn checked_log( self , base: Self ) -> Option <Self > {
2189
+ // SAFETY: We check the input to this is always positive
2190
+ let logb2 = |x: Self | unsafe { intrinsics:: ctlz_nonzero( 1 as Self ) - intrinsics:: ctlz_nonzero( x) } ;
2191
+
2192
+ if self <= 0 || base <= 1 {
2193
+ None
2194
+ } else {
2195
+ let mut n = 0 ;
2196
+ let mut r = self ;
2197
+
2198
+ // Optimization for 128 bit wide integers.
2199
+ if mem:: size_of:: <Self >( ) * 8 == 128 {
2200
+ let b = logb2( self ) / ( logb2( base) + 1 ) ;
2201
+ n += b;
2202
+ r /= base. pow( b as u32 ) ;
2203
+ }
2204
+
2205
+ while r >= base {
2206
+ r /= base;
2207
+ n += 1 ;
2208
+ }
2209
+ Some ( n)
2210
+ }
2211
+ }
2212
+ }
2213
+
2214
+ doc_comment! {
2215
+ concat!( "Returns the base 2 logarithm of the number.
2216
+
2217
+ Returns `None` if the number is lower than 1.
2218
+
2219
+ # Examples
2220
+
2221
+ ```
2222
+ #![feature(int_log)]
2223
+
2224
+ let two = 2" , stringify!( $SelfT) , ";
2225
+
2226
+ // checked_log2(2) == 1
2227
+ let result = two.checked_log2();
2228
+
2229
+ assert_eq!(result, Some(1));
2230
+ ```" ) ,
2231
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
2232
+ #[ must_use = "this returns the result of the operation, \
2233
+ without modifying the original"]
2234
+ #[ inline]
2235
+ pub fn checked_log2( self ) -> Option <Self > {
2236
+ if self <= 0 {
2237
+ None
2238
+ } else {
2239
+ // SAFETY: We just checked that this number is positive
2240
+ let log = unsafe { intrinsics:: ctlz_nonzero( 1 as Self ) - intrinsics:: ctlz_nonzero( self ) } ;
2241
+ Some ( log)
2242
+ }
2243
+ }
2244
+ }
2245
+
2246
+ doc_comment! {
2247
+ concat!( "Returns the base 10 logarithm of the number.
2248
+
2249
+ Returns `None` if the number is lower than 1.
2250
+
2251
+ # Examples
2252
+
2253
+ ```
2254
+ #![feature(int_log)]
2255
+
2256
+ let ten = 10" , stringify!( $SelfT) , ";
2257
+
2258
+ // checked_log10(10) == 1
2259
+ let result = ten.checked_log10();
2260
+
2261
+ assert_eq!(result, Some(1));
2262
+ ```" ) ,
2263
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
2264
+ #[ must_use = "this returns the result of the operation, \
2265
+ without modifying the original"]
2266
+ #[ inline]
2267
+ pub fn checked_log10( self ) -> Option <Self > {
2268
+ self . checked_log( 10 )
2269
+ }
2270
+ }
2271
+
2272
+
2273
+
2163
2274
doc_comment! {
2164
2275
concat!( "Computes the absolute value of `self`.
2165
2276
@@ -4169,6 +4280,115 @@ assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer
4169
4280
}
4170
4281
}
4171
4282
4283
+ doc_comment! {
4284
+ concat!( "Returns the logarithm of the number with respect to an arbitrary base.
4285
+
4286
+ Returns `None` if the number is negative or zero, or if the base is negative, zero, or one.
4287
+
4288
+ This method may not be optimized owing to implementation details;
4289
+ `self.checked_log2()` can produce results more efficiently for base 2, and
4290
+ `self.checked_log10()` can produce results more efficiently for base 10.
4291
+
4292
+ # Examples
4293
+
4294
+ ```
4295
+ #![feature(int_log)]
4296
+
4297
+ let five = 5" , stringify!( $SelfT) , ";
4298
+
4299
+ // log5(5) == 1
4300
+ let result = five.checked_log(5);
4301
+
4302
+ assert_eq!(result, Some(1));
4303
+ ```" ) ,
4304
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
4305
+ #[ must_use = "this returns the result of the operation, \
4306
+ without modifying the original"]
4307
+ #[ inline]
4308
+ pub fn checked_log( self , base: Self ) -> Option <Self > {
4309
+ // SAFETY: We check the input to this is always positive.
4310
+ let logb2 = |x: Self | unsafe { intrinsics:: ctlz_nonzero( 1 as Self ) - intrinsics:: ctlz_nonzero( x) } ;
4311
+
4312
+ if self <= 0 || base <= 1 {
4313
+ None
4314
+ } else {
4315
+ let mut n = 0 ;
4316
+ let mut r = self ;
4317
+
4318
+ // Optimization for 128 bit wide integers.
4319
+ if mem:: size_of:: <Self >( ) * 8 == 128 {
4320
+ let b = logb2( self ) / ( logb2( base) + 1 ) ;
4321
+ n += b;
4322
+ r /= base. pow( b as u32 ) ;
4323
+ }
4324
+
4325
+ while r >= base {
4326
+ r /= base;
4327
+ n += 1 ;
4328
+ }
4329
+ Some ( n)
4330
+ }
4331
+ }
4332
+ }
4333
+
4334
+ doc_comment! {
4335
+ concat!( "Returns the base 2 logarithm of the number.
4336
+
4337
+ Returns `None` if the number is lower than 1.
4338
+
4339
+ # Examples
4340
+
4341
+ ```
4342
+ #![feature(int_log)]
4343
+
4344
+ let two = 2" , stringify!( $SelfT) , ";
4345
+
4346
+ // checked_log2(2) == 1
4347
+ let result = two.checked_log2();
4348
+
4349
+ assert_eq!(result, Some(1));
4350
+ ```" ) ,
4351
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
4352
+ #[ must_use = "this returns the result of the operation, \
4353
+ without modifying the original"]
4354
+ #[ inline]
4355
+ pub fn checked_log2( self ) -> Option <Self > {
4356
+ if self <= 0 {
4357
+ None
4358
+ } else {
4359
+ // SAFETY: We just checked that this number is positive
4360
+ let log = unsafe { intrinsics:: ctlz_nonzero( 1 as Self ) - intrinsics:: ctlz_nonzero( self ) } ;
4361
+ Some ( log)
4362
+ }
4363
+ }
4364
+ }
4365
+
4366
+ doc_comment! {
4367
+ concat!( "Returns the base 10 logarithm of the number.
4368
+
4369
+ Returns `None` if the number is lower than 1.
4370
+
4371
+ # Examples
4372
+
4373
+ ```
4374
+ #![feature(int_log)]
4375
+
4376
+ let ten = 10" , stringify!( $SelfT) , ";
4377
+
4378
+ // checked_log10(10) == 1
4379
+ let result = ten.checked_log10();
4380
+
4381
+ assert_eq!(result, Some(1));
4382
+ ```" ) ,
4383
+ #[ unstable( feature = "int_log" , issue = "70887" ) ]
4384
+ #[ must_use = "this returns the result of the operation, \
4385
+ without modifying the original"]
4386
+ #[ inline]
4387
+ pub fn checked_log10( self ) -> Option <Self > {
4388
+ self . checked_log( 10 )
4389
+ }
4390
+ }
4391
+
4172
4392
doc_comment! {
4173
4393
concat!( "Returns `true` if and only if `self == 2^k` for some `k`.
4174
4394
0 commit comments