bit-twiddle 0.0.4 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +3 -4
- data/ext/bit_twiddle/bit_twiddle.c +377 -424
- data/ext/bit_twiddle/extconf.rb +19 -6
- data/ext/bit_twiddle/ruby23/bt_bignum.h +52 -0
- data/ext/bit_twiddle/ruby30/bt_bignum.h +83 -0
- metadata +17 -19
- data/ext/bit_twiddle/ruby21/bt_bignum.h +0 -1
- data/lib/bit_twiddle.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 25b438e0de17e4ef56155166736b08d0bfc3ba962ae8c85f837e3073ed25e76f
|
4
|
+
data.tar.gz: b6cff494a2d45bdaa06eff5299a64b32f3a3b4ff284f7c5439a40dda29905b32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5097963595ddf9773f481b771958d00315c5a9e15deaa55c1e9290a82398b42b7b4ceccc7c9b6a105b63f30f9fab49b381fcf39ab630dc90343bfaac6cecb058
|
7
|
+
data.tar.gz: 24233d812e555ed06a9c31d6a098a414ebb5e98589b638fede32b981a43adef8f10e213e22167ec1147dd0aa1d6ed5c0f13753cbd218bf7dad2852c270a85760
|
data/LICENSE
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
The program code in the 'bit-twiddle' repository (currently available at https://github.com/alexdowad/bit-twiddle) has been placed in the public domain by its author. You can do anything you want with it, anything at all. You can copy it, sell it, buy it, lease it, rent it out, put it in pawn, or use it as a down payment on a new truck. You can sing it out in the shower, or on a crowded bus. You can even inscribe it on a silk flag, and plant it on Kilimanjaro's snow-covered slopes. The possibilities are endless!
|
2
2
|
|
3
|
-
If
|
3
|
+
If 'public domain' isn't what you like, then you can use this code under a CC0 (creative commons) license. Still no good? Drop the author a note and we'll see how to fix you up.
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
|
1
|
+
Fast bitwise operations for Ruby
|
2
|
+
================================
|
2
3
|
|
3
|
-
Ruby has built-in implementations of the "workhorses" of bit manipulation: bitwise AND, OR, NOT, and XOR operations and bit shifts. This library adds more bitwise operations, which may be useful in implementing some algorithms. All the added operations are implemented in optimized C code (so this is MRI-only).
|
4
|
+
Ruby has built-in implementations of the "workhorses" of bit manipulation: bitwise AND, OR, NOT, and XOR operations and bit shifts. This library adds more bitwise operations, which may be useful in implementing some algorithms. All the added operations are implemented in optimized C code (so this is MRI-only).
|
4
5
|
|
5
6
|
Install this goodness with:
|
6
7
|
|
@@ -22,8 +23,6 @@ require "bit-twiddle/core_ext"
|
|
22
23
|
|
23
24
|
In many cases, `bit-twiddle` operations explicitly work on the low 8, 16, 32, or 64 bits of an integer. (For example, it defines `#bitreverse8`, `#bitreverse16`, `#bitreverse32`, and `#bitreverse64` methods.) If an integer's bit width is larger than the number of bits operated on, the higher-end bits are passed through unchanged.
|
24
25
|
|
25
|
-
All methods automatically convert between `Fixnum` and `Bignum` as is most appropriate to represent their result.
|
26
|
-
|
27
26
|
## Examples
|
28
27
|
|
29
28
|
### Population count
|
@@ -1,6 +1,16 @@
|
|
1
|
+
/* Fast C implementation of additional bitwise operations for Ruby
|
2
|
+
* Hand-crafted with ♥ by Alex Dowad, using ONLY the finest 1s and 0s */
|
3
|
+
|
1
4
|
#include <ruby.h>
|
2
5
|
#include "bt_bignum.h"
|
3
6
|
|
7
|
+
#ifndef HAVE_TYPE_ULONG
|
8
|
+
typedef unsigned long ulong;
|
9
|
+
#endif
|
10
|
+
#ifndef HAVE_TYPE_UCHAR
|
11
|
+
typedef unsigned char uchar;
|
12
|
+
#endif
|
13
|
+
|
4
14
|
#define fix_zero LONG2FIX(0L)
|
5
15
|
#define BIGNUM_P(x) RB_TYPE_P((x), T_BIGNUM)
|
6
16
|
|
@@ -21,11 +31,11 @@
|
|
21
31
|
#endif
|
22
32
|
|
23
33
|
#if SIZEOF_BDIGIT < 4
|
24
|
-
#error "Sorry,
|
34
|
+
#error "Sorry, Integer#bswap32 and Integer#arith_rshift32 will not work if sizeof(BDIGIT) < 4. Please report this error."
|
25
35
|
#elif SIZEOF_BDIGIT > 8
|
26
36
|
#error "Sorry, several methods will not work if sizeof(BDIGIT) > 8. Please report this error."
|
27
37
|
#elif SIZEOF_LONG > 8
|
28
|
-
#error "Sorry,
|
38
|
+
#error "Sorry, Integer#arith_rshift64 will not work if sizeof(long) > 8. Please report this error."
|
29
39
|
#endif
|
30
40
|
|
31
41
|
#if HAVE_BSWAP16 == 0
|
@@ -50,7 +60,7 @@ bnum_greater(VALUE bnum, BDIGIT value)
|
|
50
60
|
}
|
51
61
|
|
52
62
|
static long
|
53
|
-
value_to_shiftdist(VALUE shiftdist,
|
63
|
+
value_to_shiftdist(VALUE shiftdist, unsigned int bits)
|
54
64
|
{
|
55
65
|
for (;;) {
|
56
66
|
if (FIXNUM_P(shiftdist)) {
|
@@ -81,12 +91,12 @@ value_to_rotdist(VALUE rotdist, long bits, long mask)
|
|
81
91
|
rdist = FIX2LONG(rotdist) % bits;
|
82
92
|
if (rdist < 0)
|
83
93
|
rdist += bits;
|
84
|
-
return rdist;
|
94
|
+
return (ulong)rdist;
|
85
95
|
} else if (BIGNUM_P(rotdist)) {
|
86
96
|
rdist = *RBIGNUM_DIGITS(rotdist) & mask;
|
87
97
|
if (RBIGNUM_NEGATIVE_P(rotdist))
|
88
98
|
rdist = bits - rdist;
|
89
|
-
return rdist;
|
99
|
+
return (ulong)rdist;
|
90
100
|
} else {
|
91
101
|
rotdist = rb_to_int(rotdist);
|
92
102
|
}
|
@@ -99,22 +109,22 @@ store_64_into_bnum(VALUE bnum, uint64_t int64)
|
|
99
109
|
BDIGIT *dest = RBIGNUM_DIGITS(bnum);
|
100
110
|
size_t len = RBIGNUM_LEN(bnum);
|
101
111
|
|
102
|
-
|
112
|
+
#if (SIZEOF_BDIGIT == 8)
|
103
113
|
*dest = int64;
|
104
|
-
|
114
|
+
#else
|
105
115
|
if (len > 1) {
|
106
|
-
*dest = int64;
|
107
|
-
*(dest+1) = int64 >> 32;
|
116
|
+
*dest = (uint32_t)int64;
|
117
|
+
*(dest+1) = (uint32_t)(int64 >> 32);
|
108
118
|
} else if ((int64 & (0xFFFFFFFFULL << 32)) == 0) {
|
109
119
|
/* the high 4 bytes are zero anyways */
|
110
|
-
*dest = int64;
|
120
|
+
*dest = (uint32_t)int64;
|
111
121
|
} else {
|
112
122
|
rb_big_resize(bnum, 2);
|
113
123
|
dest = RBIGNUM_DIGITS(bnum); /* may have moved */
|
114
|
-
*dest = int64;
|
115
|
-
*(dest+1) = int64 >> 32;
|
124
|
+
*dest = (uint32_t)int64;
|
125
|
+
*(dest+1) = (uint32_t)(int64 >> 32);
|
116
126
|
}
|
117
|
-
|
127
|
+
#endif
|
118
128
|
}
|
119
129
|
|
120
130
|
static uint64_t
|
@@ -201,24 +211,30 @@ modify_lo64_in_bignum(VALUE bnum, uint64_t lo64)
|
|
201
211
|
return result;
|
202
212
|
}
|
203
213
|
|
204
|
-
/*
|
205
|
-
*
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
214
|
+
/* Now start defining implementations of actual Ruby methods
|
215
|
+
* First two helper macros: */
|
216
|
+
#define def_int_method(name) \
|
217
|
+
static VALUE int_ ## name(VALUE integer) { \
|
218
|
+
if (FIXNUM_P(integer)) \
|
219
|
+
return fnum_ ## name(integer); \
|
220
|
+
else \
|
221
|
+
return bnum_ ## name(integer); \
|
222
|
+
}
|
223
|
+
#define def_int_method_with_arg(name) \
|
224
|
+
static VALUE int_ ## name(VALUE integer, VALUE arg) { \
|
225
|
+
if (FIXNUM_P(integer)) \
|
226
|
+
return fnum_ ## name(integer, arg); \
|
227
|
+
else \
|
228
|
+
return bnum_ ## name(integer, arg); \
|
229
|
+
}
|
230
|
+
|
215
231
|
static VALUE
|
216
232
|
fnum_popcount(VALUE fnum)
|
217
233
|
{
|
218
234
|
long value = FIX2LONG(fnum);
|
219
235
|
if (value < 0)
|
220
236
|
rb_raise(rb_eRangeError, "can't take popcount of a negative number");
|
221
|
-
return LONG2FIX(__builtin_popcountl(value));
|
237
|
+
return LONG2FIX(__builtin_popcountl((ulong)value));
|
222
238
|
}
|
223
239
|
|
224
240
|
static VALUE
|
@@ -239,16 +255,28 @@ bnum_popcount(VALUE bnum)
|
|
239
255
|
return LONG2FIX(bits);
|
240
256
|
}
|
241
257
|
|
258
|
+
/* Document-method: Integer#popcount
|
259
|
+
* Return the number of 1 bits in this integer.
|
260
|
+
*
|
261
|
+
* If the receiver is negative, raise `RangeError`.
|
262
|
+
*
|
263
|
+
* @example
|
264
|
+
* 7.popcount # => 3
|
265
|
+
* 255.popcount # => 8
|
266
|
+
* @return [Integer]
|
267
|
+
*/
|
268
|
+
def_int_method(popcount);
|
269
|
+
|
242
270
|
/* Return the number of 1 bits in all the bytes of this `String`.
|
243
271
|
* @example
|
244
272
|
* "abc".popcount # => 10
|
245
|
-
* @return [
|
273
|
+
* @return [Integer]
|
246
274
|
*/
|
247
275
|
static VALUE
|
248
276
|
str_popcount(VALUE str)
|
249
277
|
{
|
250
|
-
|
251
|
-
|
278
|
+
uchar *p = (uchar*)RSTRING_PTR(str);
|
279
|
+
long length = RSTRING_LEN(str);
|
252
280
|
long bits = 0;
|
253
281
|
|
254
282
|
/* This could be made faster by processing 4/8 bytes at a time */
|
@@ -259,18 +287,6 @@ str_popcount(VALUE str)
|
|
259
287
|
return LONG2FIX(bits);
|
260
288
|
}
|
261
289
|
|
262
|
-
/* Document-method: Fixnum#lo_bit
|
263
|
-
* Document-method: Bignum#lo_bit
|
264
|
-
* Return the index of the lowest 1 bit, where the least-significant bit is index 1.
|
265
|
-
* If the receiver is 0, return 0.
|
266
|
-
*
|
267
|
-
* If the receiver is negative, raise `RangeError`.
|
268
|
-
*
|
269
|
-
* @example
|
270
|
-
* 1.lo_bit # => 1
|
271
|
-
* 128.lo_bit # => 8
|
272
|
-
* @return [Fixnum]
|
273
|
-
*/
|
274
290
|
static VALUE
|
275
291
|
fnum_lo_bit(VALUE fnum)
|
276
292
|
{
|
@@ -306,18 +322,19 @@ bnum_lo_bit(VALUE bnum)
|
|
306
322
|
return LONG2FIX(bits);
|
307
323
|
}
|
308
324
|
|
309
|
-
/* Document-method:
|
310
|
-
*
|
311
|
-
* Return the index of the highest 1 bit, where the least-significant bit is index 1.
|
325
|
+
/* Document-method: Integer#lo_bit
|
326
|
+
* Return the index of the lowest 1 bit, where the least-significant bit is index 1.
|
312
327
|
* If the receiver is 0, return 0.
|
313
328
|
*
|
314
329
|
* If the receiver is negative, raise `RangeError`.
|
315
330
|
*
|
316
331
|
* @example
|
317
|
-
* 1.
|
318
|
-
*
|
319
|
-
* @return [
|
332
|
+
* 1.lo_bit # => 1
|
333
|
+
* 128.lo_bit # => 8
|
334
|
+
* @return [Integer]
|
320
335
|
*/
|
336
|
+
def_int_method(lo_bit);
|
337
|
+
|
321
338
|
static VALUE
|
322
339
|
fnum_hi_bit(VALUE fnum)
|
323
340
|
{
|
@@ -333,7 +350,7 @@ static VALUE
|
|
333
350
|
bnum_hi_bit(VALUE bnum)
|
334
351
|
{
|
335
352
|
BDIGIT *digit = RBIGNUM_DIGITS(bnum) + (RBIGNUM_LEN(bnum)-1);
|
336
|
-
|
353
|
+
ulong bits = (sizeof(BDIGIT) * 8) * RBIGNUM_LEN(bnum);
|
337
354
|
|
338
355
|
if (RBIGNUM_NEGATIVE_P(bnum))
|
339
356
|
rb_raise(rb_eRangeError, "can't find highest 1 bit in a negative number");
|
@@ -347,47 +364,49 @@ bnum_hi_bit(VALUE bnum)
|
|
347
364
|
return LONG2FIX(bits);
|
348
365
|
}
|
349
366
|
|
350
|
-
/* Document-method:
|
351
|
-
*
|
352
|
-
*
|
367
|
+
/* Document-method: Integer#hi_bit
|
368
|
+
* Return the index of the highest 1 bit, where the least-significant bit is index 1.
|
369
|
+
* If the receiver is 0, return 0.
|
353
370
|
*
|
354
371
|
* If the receiver is negative, raise `RangeError`.
|
355
372
|
*
|
356
373
|
* @example
|
357
|
-
*
|
358
|
-
*
|
374
|
+
* 1.hi_bit # => 1
|
375
|
+
* 255.hi_bit # => 8
|
359
376
|
* @return [Integer]
|
360
377
|
*/
|
378
|
+
def_int_method(hi_bit);
|
379
|
+
|
361
380
|
static VALUE
|
362
381
|
fnum_bswap16(VALUE fnum)
|
363
382
|
{
|
364
383
|
long value = FIX2LONG(fnum);
|
365
384
|
if (value < 0)
|
366
385
|
rb_raise(rb_eRangeError, "can't swap bytes in a negative number");
|
367
|
-
return LONG2FIX((value & ~
|
386
|
+
return LONG2FIX(((ulong)value & ~0xFFFFUL) | __builtin_bswap16((uint16_t)value));
|
368
387
|
}
|
369
388
|
|
370
389
|
static VALUE
|
371
390
|
bnum_bswap16(VALUE bnum)
|
372
391
|
{
|
373
392
|
if (RBIGNUM_POSITIVE_P(bnum))
|
374
|
-
return modify_lo16_in_bignum(bnum, __builtin_bswap16(*RBIGNUM_DIGITS(bnum)));
|
393
|
+
return modify_lo16_in_bignum(bnum, __builtin_bswap16((uint16_t)*RBIGNUM_DIGITS(bnum)));
|
375
394
|
else
|
376
395
|
rb_raise(rb_eRangeError, "can't swap bytes in a negative number");
|
377
396
|
}
|
378
397
|
|
379
|
-
/* Document-method:
|
380
|
-
*
|
381
|
-
* Reverse the least-significant 4 bytes of this integer.
|
398
|
+
/* Document-method: Integer#bswap16
|
399
|
+
* Reverse the least-significant and second least-significant bytes of this integer.
|
382
400
|
*
|
383
|
-
*
|
384
|
-
* of a 32-bit integer. If the receiver is negative, raise `RangeError`.
|
401
|
+
* If the receiver is negative, raise `RangeError`.
|
385
402
|
*
|
386
403
|
* @example
|
387
|
-
*
|
388
|
-
*
|
404
|
+
* 0xFF00.bswap16 # => 255
|
405
|
+
* 0x00FF.bswap16 # => 65280
|
389
406
|
* @return [Integer]
|
390
407
|
*/
|
408
|
+
def_int_method(bswap16);
|
409
|
+
|
391
410
|
static VALUE
|
392
411
|
fnum_bswap32(VALUE fnum)
|
393
412
|
{
|
@@ -403,7 +422,7 @@ fnum_bswap32(VALUE fnum)
|
|
403
422
|
* That is why we have to use a '2NUM' function, not '2FIX' */
|
404
423
|
return ULONG2NUM(__builtin_bswap32(FIX2LONG(fnum)));
|
405
424
|
else
|
406
|
-
return LONG2FIX((value & ~
|
425
|
+
return LONG2FIX(((ulong)value & ~0xFFFFFFFFUL) | __builtin_bswap32((uint32_t)value));
|
407
426
|
}
|
408
427
|
|
409
428
|
static VALUE
|
@@ -415,25 +434,26 @@ bnum_bswap32(VALUE bnum)
|
|
415
434
|
rb_raise(rb_eRangeError, "can't swap bytes in a negative number");
|
416
435
|
}
|
417
436
|
|
418
|
-
/* Document-method:
|
419
|
-
*
|
420
|
-
* Reverse the least-significant 8 bytes of this integer.
|
437
|
+
/* Document-method: Integer#bswap32
|
438
|
+
* Reverse the least-significant 4 bytes of this integer.
|
421
439
|
*
|
422
440
|
* Does not reverse bits within each byte. This can be used to swap endianness
|
423
|
-
* of a
|
441
|
+
* of a 32-bit integer. If the receiver is negative, raise `RangeError`.
|
424
442
|
*
|
425
443
|
* @example
|
426
|
-
* 0xaabbccdd.
|
444
|
+
* 0xaabbccdd.bswap32.to_s(16) # => "ddccbbaa"
|
427
445
|
*
|
428
446
|
* @return [Integer]
|
429
447
|
*/
|
448
|
+
def_int_method(bswap32);
|
449
|
+
|
430
450
|
static VALUE
|
431
451
|
fnum_bswap64(VALUE fnum)
|
432
452
|
{
|
433
453
|
long value = FIX2LONG(fnum);
|
434
454
|
if (value < 0)
|
435
455
|
rb_raise(rb_eRangeError, "can't swap bytes in a negative number");
|
436
|
-
return ULL2NUM(__builtin_bswap64(value));
|
456
|
+
return ULL2NUM(__builtin_bswap64((uint64_t)value));
|
437
457
|
}
|
438
458
|
|
439
459
|
static VALUE
|
@@ -445,6 +465,19 @@ bnum_bswap64(VALUE bnum)
|
|
445
465
|
rb_raise(rb_eRangeError, "can't swap bytes in a negative number");
|
446
466
|
}
|
447
467
|
|
468
|
+
/* Document-method: Integer#bswap64
|
469
|
+
* Reverse the least-significant 8 bytes of this integer.
|
470
|
+
*
|
471
|
+
* Does not reverse bits within each byte. This can be used to swap endianness
|
472
|
+
* of a 64-bit integer. If the receiver is negative, raise `RangeError`.
|
473
|
+
*
|
474
|
+
* @example
|
475
|
+
* 0xaabbccdd.bswap64.to_s(16) # => "ddccbbaa00000000"
|
476
|
+
*
|
477
|
+
* @return [Integer]
|
478
|
+
*/
|
479
|
+
def_int_method(bswap64);
|
480
|
+
|
448
481
|
#define def_rot_helpers(bits) \
|
449
482
|
static inline uint##bits##_t rrot##bits(uint##bits##_t value, VALUE rotdist) { \
|
450
483
|
ulong rotd = value_to_rotdist(rotdist, bits, bits-1); \
|
@@ -460,102 +493,92 @@ def_rot_helpers(16);
|
|
460
493
|
def_rot_helpers(32);
|
461
494
|
def_rot_helpers(64);
|
462
495
|
|
463
|
-
/* Document-method: Fixnum#rrot8
|
464
|
-
* Document-method: Bignum#rrot8
|
465
|
-
* Right-rotation ("circular shift") of the low 8 bits in this integer.
|
466
|
-
*
|
467
|
-
* If the rotate distance is negative, the bit rotation will be to the left
|
468
|
-
* instead.
|
469
|
-
*
|
470
|
-
* @example
|
471
|
-
* 0b01110001.rrot8(1).to_s(2) # => "10111000"
|
472
|
-
* 0b01110001.rrot8(3).to_s(2) # => "101110"
|
473
|
-
*
|
474
|
-
* @param rotdist [Integer] Number of bit positions to rotate by
|
475
|
-
* @return [Integer]
|
476
|
-
*/
|
477
496
|
static VALUE
|
478
497
|
fnum_rrot8(VALUE fnum, VALUE rotdist)
|
479
498
|
{
|
480
499
|
long value = FIX2LONG(fnum);
|
481
|
-
return LONG2FIX((value & ~
|
500
|
+
return LONG2FIX(((ulong)value & ~0xFFUL) | rrot8((uint8_t)value, rotdist));
|
482
501
|
}
|
483
502
|
|
484
503
|
static VALUE
|
485
504
|
bnum_rrot8(VALUE bnum, VALUE rotdist)
|
486
505
|
{
|
487
|
-
return modify_lo8_in_bignum(bnum, rrot8(*RBIGNUM_DIGITS(bnum), rotdist));
|
506
|
+
return modify_lo8_in_bignum(bnum, rrot8((uint8_t)*RBIGNUM_DIGITS(bnum), rotdist));
|
488
507
|
}
|
489
508
|
|
490
|
-
/* Document-method:
|
491
|
-
*
|
492
|
-
* Right-rotation ("circular shift") of the low 16 bits in this integer.
|
509
|
+
/* Document-method: Integer#rrot8
|
510
|
+
* Right-rotation ("circular shift") of the low 8 bits in this integer.
|
493
511
|
*
|
494
512
|
* If the rotate distance is negative, the bit rotation will be to the left
|
495
513
|
* instead.
|
496
514
|
*
|
497
515
|
* @example
|
498
|
-
*
|
499
|
-
*
|
516
|
+
* 0b01110001.rrot8(1).to_s(2) # => "10111000"
|
517
|
+
* 0b01110001.rrot8(3).to_s(2) # => "101110"
|
500
518
|
*
|
501
519
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
502
520
|
* @return [Integer]
|
503
521
|
*/
|
522
|
+
def_int_method_with_arg(rrot8);
|
523
|
+
|
504
524
|
static VALUE
|
505
525
|
fnum_rrot16(VALUE fnum, VALUE rotdist)
|
506
526
|
{
|
507
527
|
long value = FIX2LONG(fnum);
|
508
|
-
return LONG2FIX((value & ~
|
528
|
+
return LONG2FIX(((ulong)value & ~0xFFFFUL) | rrot16((uint16_t)value, rotdist));
|
509
529
|
}
|
510
530
|
|
511
531
|
static VALUE
|
512
532
|
bnum_rrot16(VALUE bnum, VALUE rotdist)
|
513
533
|
{
|
514
|
-
return modify_lo16_in_bignum(bnum, rrot16(*RBIGNUM_DIGITS(bnum), rotdist));
|
534
|
+
return modify_lo16_in_bignum(bnum, rrot16((uint16_t)*RBIGNUM_DIGITS(bnum), rotdist));
|
515
535
|
}
|
516
536
|
|
517
|
-
/* Document-method:
|
518
|
-
*
|
519
|
-
* Right-rotation ("circular shift") of the low 32 bits in this integer.
|
537
|
+
/* Document-method: Integer#rrot16
|
538
|
+
* Right-rotation ("circular shift") of the low 16 bits in this integer.
|
520
539
|
*
|
521
540
|
* If the rotate distance is negative, the bit rotation will be to the left
|
522
541
|
* instead.
|
523
542
|
*
|
524
543
|
* @example
|
525
|
-
*
|
544
|
+
* 0b0111000101110001.rrot16(1).to_s(2) # => "1011100010111000"
|
545
|
+
* 0b0111000101110001.rrot16(3).to_s(2) # => "10111000101110"
|
526
546
|
*
|
527
547
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
528
548
|
* @return [Integer]
|
529
549
|
*/
|
550
|
+
def_int_method_with_arg(rrot16);
|
551
|
+
|
530
552
|
static VALUE
|
531
553
|
fnum_rrot32(VALUE fnum, VALUE rotdist)
|
532
554
|
{
|
533
555
|
long value = FIX2LONG(fnum);
|
534
556
|
if (SIZEOF_LONG == 8)
|
535
|
-
return LONG2FIX((value & ~
|
557
|
+
return LONG2FIX(((ulong)value & ~0xFFFFFFFFUL) | rrot32((uint32_t)value, rotdist));
|
536
558
|
else
|
537
|
-
return ULONG2NUM(rrot32(value, rotdist));
|
559
|
+
return ULONG2NUM(rrot32((uint32_t)value, rotdist));
|
538
560
|
}
|
539
561
|
|
540
562
|
static VALUE
|
541
563
|
bnum_rrot32(VALUE bnum, VALUE rotdist)
|
542
564
|
{
|
543
|
-
return modify_lo32_in_bignum(bnum, rrot32(*RBIGNUM_DIGITS(bnum), rotdist));
|
565
|
+
return modify_lo32_in_bignum(bnum, rrot32((uint32_t)*RBIGNUM_DIGITS(bnum), rotdist));
|
544
566
|
}
|
545
567
|
|
546
|
-
/* Document-method:
|
547
|
-
*
|
548
|
-
* Right-rotation ("circular shift") of the low 64 bits in this integer.
|
568
|
+
/* Document-method: Integer#rrot32
|
569
|
+
* Right-rotation ("circular shift") of the low 32 bits in this integer.
|
549
570
|
*
|
550
571
|
* If the rotate distance is negative, the bit rotation will be to the left
|
551
572
|
* instead.
|
552
573
|
*
|
553
574
|
* @example
|
554
|
-
*
|
575
|
+
* 0xaabbccdd.rrot32(4).to_s(16) # => "daabbccd"
|
555
576
|
*
|
556
577
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
557
578
|
* @return [Integer]
|
558
579
|
*/
|
580
|
+
def_int_method_with_arg(rrot32);
|
581
|
+
|
559
582
|
static VALUE
|
560
583
|
fnum_rrot64(VALUE fnum, VALUE rotdist)
|
561
584
|
{
|
@@ -568,99 +591,103 @@ bnum_rrot64(VALUE bnum, VALUE rotdist)
|
|
568
591
|
return modify_lo64_in_bignum(bnum, rrot64(load_64_from_bignum(bnum), rotdist));
|
569
592
|
}
|
570
593
|
|
571
|
-
/* Document-method:
|
572
|
-
*
|
573
|
-
* Left-rotation ("circular shift") of the low 8 bits in this integer.
|
594
|
+
/* Document-method: Integer#rrot64
|
595
|
+
* Right-rotation ("circular shift") of the low 64 bits in this integer.
|
574
596
|
*
|
575
|
-
* If the rotate distance is negative, the bit rotation will be to the
|
597
|
+
* If the rotate distance is negative, the bit rotation will be to the left
|
576
598
|
* instead.
|
577
599
|
*
|
578
600
|
* @example
|
579
|
-
*
|
580
|
-
* 0b01110001.lrot8(3).to_s(2) # => "10001011"
|
601
|
+
* 0x11223344aabbccdd.rrot64(4).to_s(16) # => "d11223344aabbccd"
|
581
602
|
*
|
582
603
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
583
604
|
* @return [Integer]
|
584
605
|
*/
|
606
|
+
def_int_method_with_arg(rrot64);
|
607
|
+
|
585
608
|
static VALUE
|
586
609
|
fnum_lrot8(VALUE fnum, VALUE rotdist)
|
587
610
|
{
|
588
611
|
long value = FIX2LONG(fnum);
|
589
|
-
return LONG2FIX((value & ~
|
612
|
+
return LONG2FIX(((ulong)value & ~0xFFUL) | lrot8((uint8_t)value, rotdist));
|
590
613
|
}
|
591
614
|
|
592
615
|
static VALUE
|
593
616
|
bnum_lrot8(VALUE bnum, VALUE rotdist)
|
594
617
|
{
|
595
|
-
return modify_lo8_in_bignum(bnum, lrot8(*RBIGNUM_DIGITS(bnum), rotdist));
|
618
|
+
return modify_lo8_in_bignum(bnum, lrot8((uint8_t)*RBIGNUM_DIGITS(bnum), rotdist));
|
596
619
|
}
|
597
620
|
|
598
|
-
/* Document-method:
|
599
|
-
*
|
600
|
-
* Left-rotation ("circular shift") of the low 16 bits in this integer.
|
621
|
+
/* Document-method: Integer#lrot8
|
622
|
+
* Left-rotation ("circular shift") of the low 8 bits in this integer.
|
601
623
|
*
|
602
624
|
* If the rotate distance is negative, the bit rotation will be to the right
|
603
625
|
* instead.
|
604
626
|
*
|
605
627
|
* @example
|
606
|
-
*
|
607
|
-
*
|
628
|
+
* 0b01110001.lrot8(1).to_s(2) # => "11100010"
|
629
|
+
* 0b01110001.lrot8(3).to_s(2) # => "10001011"
|
608
630
|
*
|
609
631
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
610
632
|
* @return [Integer]
|
611
633
|
*/
|
634
|
+
def_int_method_with_arg(lrot8);
|
635
|
+
|
612
636
|
static VALUE
|
613
637
|
fnum_lrot16(VALUE fnum, VALUE rotdist)
|
614
638
|
{
|
615
639
|
long value = FIX2LONG(fnum);
|
616
|
-
return LONG2FIX((value & ~
|
640
|
+
return LONG2FIX(((ulong)value & ~0xFFFFUL) | lrot16((uint16_t)value, rotdist));
|
617
641
|
}
|
618
642
|
|
619
643
|
static VALUE
|
620
644
|
bnum_lrot16(VALUE bnum, VALUE rotdist)
|
621
645
|
{
|
622
|
-
return modify_lo16_in_bignum(bnum, lrot16(*RBIGNUM_DIGITS(bnum), rotdist));
|
646
|
+
return modify_lo16_in_bignum(bnum, lrot16((uint16_t)*RBIGNUM_DIGITS(bnum), rotdist));
|
623
647
|
}
|
624
648
|
|
625
|
-
/* Document-method:
|
626
|
-
*
|
627
|
-
* Left-rotation ("circular shift") of the low 32 bits in this integer.
|
649
|
+
/* Document-method: Integer#lrot16
|
650
|
+
* Left-rotation ("circular shift") of the low 16 bits in this integer.
|
628
651
|
*
|
629
652
|
* If the rotate distance is negative, the bit rotation will be to the right
|
630
653
|
* instead.
|
631
654
|
*
|
632
655
|
* @example
|
633
|
-
*
|
656
|
+
* 0b0111000101110001.lrot16(1).to_s(2) # => "1110001011100010"
|
657
|
+
* 0b0111000101110001.lrot16(3).to_s(2) # => "1000101110001011"
|
634
658
|
*
|
635
659
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
636
660
|
* @return [Integer]
|
637
661
|
*/
|
662
|
+
def_int_method_with_arg(lrot16);
|
663
|
+
|
638
664
|
static VALUE
|
639
665
|
fnum_lrot32(VALUE fnum, VALUE rotdist)
|
640
666
|
{
|
641
667
|
long value = FIX2LONG(fnum);
|
642
|
-
return LONG2FIX((value & ~
|
668
|
+
return LONG2FIX(((ulong)value & ~0xFFFFFFFFUL) | lrot32((uint32_t)value, rotdist));
|
643
669
|
}
|
644
670
|
|
645
671
|
static VALUE
|
646
672
|
bnum_lrot32(VALUE bnum, VALUE rotdist)
|
647
673
|
{
|
648
|
-
return modify_lo32_in_bignum(bnum, lrot32(*RBIGNUM_DIGITS(bnum), rotdist));
|
674
|
+
return modify_lo32_in_bignum(bnum, lrot32((uint32_t)*RBIGNUM_DIGITS(bnum), rotdist));
|
649
675
|
}
|
650
676
|
|
651
|
-
/* Document-method:
|
652
|
-
*
|
653
|
-
* Left-rotation ("circular shift") of the low 64 bits in this integer.
|
677
|
+
/* Document-method: Integer#lrot32
|
678
|
+
* Left-rotation ("circular shift") of the low 32 bits in this integer.
|
654
679
|
*
|
655
680
|
* If the rotate distance is negative, the bit rotation will be to the right
|
656
681
|
* instead.
|
657
682
|
*
|
658
683
|
* @example
|
659
|
-
*
|
684
|
+
* 0xaabbccdd.lrot32(4).to_s(16) # => "abbccdda"
|
660
685
|
*
|
661
686
|
* @param rotdist [Integer] Number of bit positions to rotate by
|
662
687
|
* @return [Integer]
|
663
688
|
*/
|
689
|
+
def_int_method_with_arg(lrot32);
|
690
|
+
|
664
691
|
static VALUE
|
665
692
|
fnum_lrot64(VALUE fnum, VALUE rotdist)
|
666
693
|
{
|
@@ -673,6 +700,20 @@ bnum_lrot64(VALUE bnum, VALUE rotdist)
|
|
673
700
|
return modify_lo64_in_bignum(bnum, lrot64(load_64_from_bignum(bnum), rotdist));
|
674
701
|
}
|
675
702
|
|
703
|
+
/* Document-method: Integer#lrot64
|
704
|
+
* Left-rotation ("circular shift") of the low 64 bits in this integer.
|
705
|
+
*
|
706
|
+
* If the rotate distance is negative, the bit rotation will be to the right
|
707
|
+
* instead.
|
708
|
+
*
|
709
|
+
* @example
|
710
|
+
* 0x11223344aabbccdd.lrot64(4).to_s(16) # => "1223344aabbccdd1"
|
711
|
+
*
|
712
|
+
* @param rotdist [Integer] Number of bit positions to rotate by
|
713
|
+
* @return [Integer]
|
714
|
+
*/
|
715
|
+
def_int_method_with_arg(lrot64);
|
716
|
+
|
676
717
|
#define def_shift_helpers(bits) \
|
677
718
|
static uint##bits##_t lshift##bits(uint##bits##_t value, VALUE shiftdist) { \
|
678
719
|
long sdist = value_to_shiftdist(shiftdist, bits); \
|
@@ -711,21 +752,6 @@ def_shift_helpers(16);
|
|
711
752
|
def_shift_helpers(32);
|
712
753
|
def_shift_helpers(64);
|
713
754
|
|
714
|
-
/* Document-method: Fixnum#lshift8
|
715
|
-
* Document-method: Bignum#lshift8
|
716
|
-
* Left-shift of the low 8 bits in this integer.
|
717
|
-
*
|
718
|
-
* If the shift distance is negative, a right shift will be performed instead.
|
719
|
-
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
720
|
-
* more than 7 or less than -7, the low 8 bits will all be zeroed.
|
721
|
-
*
|
722
|
-
* @example
|
723
|
-
* 0x11223344.lshift8(1).to_s(16) # => "11223388"
|
724
|
-
* 0x11223344.lshift8(2).to_s(16) # => "11223310"
|
725
|
-
*
|
726
|
-
* @param shiftdist [Integer] Number of bit positions to shift by
|
727
|
-
* @return [Integer]
|
728
|
-
*/
|
729
755
|
static VALUE
|
730
756
|
fnum_lshift8(VALUE fnum, VALUE shiftdist)
|
731
757
|
{
|
@@ -733,7 +759,7 @@ fnum_lshift8(VALUE fnum, VALUE shiftdist)
|
|
733
759
|
if (shiftdist == fix_zero)
|
734
760
|
return fnum;
|
735
761
|
else
|
736
|
-
return LONG2FIX((value & ~
|
762
|
+
return LONG2FIX(((ulong)value & ~0xFFUL) | lshift8((uint8_t)value, shiftdist));
|
737
763
|
}
|
738
764
|
|
739
765
|
static VALUE
|
@@ -742,24 +768,25 @@ bnum_lshift8(VALUE bnum, VALUE shiftdist)
|
|
742
768
|
if (shiftdist == fix_zero)
|
743
769
|
return bnum;
|
744
770
|
else
|
745
|
-
return modify_lo8_in_bignum(bnum, lshift8(*RBIGNUM_DIGITS(bnum), shiftdist));
|
771
|
+
return modify_lo8_in_bignum(bnum, lshift8((uint8_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
746
772
|
}
|
747
773
|
|
748
|
-
/* Document-method:
|
749
|
-
*
|
750
|
-
* Left-shift of the low 16 bits in this integer.
|
774
|
+
/* Document-method: Integer#lshift8
|
775
|
+
* Left-shift of the low 8 bits in this integer.
|
751
776
|
*
|
752
777
|
* If the shift distance is negative, a right shift will be performed instead.
|
753
778
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
754
|
-
* more than
|
779
|
+
* more than 7 or less than -7, the low 8 bits will all be zeroed.
|
755
780
|
*
|
756
781
|
* @example
|
757
|
-
* 0x11223344.
|
758
|
-
* 0x11223344.
|
782
|
+
* 0x11223344.lshift8(1).to_s(16) # => "11223388"
|
783
|
+
* 0x11223344.lshift8(2).to_s(16) # => "11223310"
|
759
784
|
*
|
760
785
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
761
786
|
* @return [Integer]
|
762
787
|
*/
|
788
|
+
def_int_method_with_arg(lshift8);
|
789
|
+
|
763
790
|
static VALUE
|
764
791
|
fnum_lshift16(VALUE fnum, VALUE shiftdist)
|
765
792
|
{
|
@@ -767,7 +794,7 @@ fnum_lshift16(VALUE fnum, VALUE shiftdist)
|
|
767
794
|
if (shiftdist == fix_zero)
|
768
795
|
return fnum;
|
769
796
|
else
|
770
|
-
return LONG2FIX((value & ~
|
797
|
+
return LONG2FIX(((ulong)value & ~0xFFFFUL) | lshift16((uint16_t)value, shiftdist));
|
771
798
|
}
|
772
799
|
|
773
800
|
static VALUE
|
@@ -776,24 +803,25 @@ bnum_lshift16(VALUE bnum, VALUE shiftdist)
|
|
776
803
|
if (shiftdist == fix_zero)
|
777
804
|
return bnum;
|
778
805
|
else
|
779
|
-
return modify_lo16_in_bignum(bnum, lshift16(*RBIGNUM_DIGITS(bnum), shiftdist));
|
806
|
+
return modify_lo16_in_bignum(bnum, lshift16((uint16_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
780
807
|
}
|
781
808
|
|
782
|
-
/* Document-method:
|
783
|
-
*
|
784
|
-
* Left-shift of the low 32 bits in this integer.
|
809
|
+
/* Document-method: Integer#lshift16
|
810
|
+
* Left-shift of the low 16 bits in this integer.
|
785
811
|
*
|
786
812
|
* If the shift distance is negative, a right shift will be performed instead.
|
787
813
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
788
|
-
* more than
|
814
|
+
* more than 15 or less than -15, the low 16 bits will all be zeroed.
|
789
815
|
*
|
790
816
|
* @example
|
791
|
-
* 0x11223344.
|
792
|
-
* 0x11223344.
|
817
|
+
* 0x11223344.lshift16(1).to_s(16) # => "11226688"
|
818
|
+
* 0x11223344.lshift16(2).to_s(16) # => "1122cd10"
|
793
819
|
*
|
794
820
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
795
821
|
* @return [Integer]
|
796
822
|
*/
|
823
|
+
def_int_method_with_arg(lshift16);
|
824
|
+
|
797
825
|
static VALUE
|
798
826
|
fnum_lshift32(VALUE fnum, VALUE shiftdist)
|
799
827
|
{
|
@@ -801,7 +829,7 @@ fnum_lshift32(VALUE fnum, VALUE shiftdist)
|
|
801
829
|
if (shiftdist == fix_zero)
|
802
830
|
return fnum;
|
803
831
|
else
|
804
|
-
return LONG2FIX((value & ~
|
832
|
+
return LONG2FIX(((ulong)value & ~0xFFFFFFFFUL) | lshift32((uint32_t)value, shiftdist));
|
805
833
|
}
|
806
834
|
|
807
835
|
static VALUE
|
@@ -810,24 +838,25 @@ bnum_lshift32(VALUE bnum, VALUE shiftdist)
|
|
810
838
|
if (shiftdist == fix_zero)
|
811
839
|
return bnum;
|
812
840
|
else
|
813
|
-
return modify_lo32_in_bignum(bnum, lshift32(*RBIGNUM_DIGITS(bnum), shiftdist));
|
841
|
+
return modify_lo32_in_bignum(bnum, lshift32((uint32_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
814
842
|
}
|
815
843
|
|
816
|
-
/* Document-method:
|
817
|
-
*
|
818
|
-
* Left-shift of the low 64 bits in this integer.
|
844
|
+
/* Document-method: Integer#lshift32
|
845
|
+
* Left-shift of the low 32 bits in this integer.
|
819
846
|
*
|
820
847
|
* If the shift distance is negative, a right shift will be performed instead.
|
821
848
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
822
|
-
* more than
|
849
|
+
* more than 31 or less than -31, the low 32 bits will all be zeroed.
|
823
850
|
*
|
824
851
|
* @example
|
825
|
-
*
|
826
|
-
*
|
852
|
+
* 0x11223344.lshift32(1).to_s(16) # => "22446688"
|
853
|
+
* 0x11223344.lshift32(2).to_s(16) # => "4488cd10"
|
827
854
|
*
|
828
855
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
829
856
|
* @return [Integer]
|
830
857
|
*/
|
858
|
+
def_int_method_with_arg(lshift32);
|
859
|
+
|
831
860
|
static VALUE
|
832
861
|
fnum_lshift64(VALUE fnum, VALUE shiftdist)
|
833
862
|
{
|
@@ -852,21 +881,22 @@ bnum_lshift64(VALUE bnum, VALUE shiftdist)
|
|
852
881
|
return modify_lo64_in_bignum(bnum, lshift64(load_64_from_bignum(bnum), shiftdist));
|
853
882
|
}
|
854
883
|
|
855
|
-
/* Document-method:
|
856
|
-
*
|
857
|
-
* Right-shift of the low 8 bits in this integer.
|
884
|
+
/* Document-method: Integer#lshift64
|
885
|
+
* Left-shift of the low 64 bits in this integer.
|
858
886
|
*
|
859
|
-
* If the shift distance is negative, a
|
887
|
+
* If the shift distance is negative, a right shift will be performed instead.
|
860
888
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
861
|
-
* more than
|
889
|
+
* more than 63 or less than -63, the low 64 bits will all be zeroed.
|
862
890
|
*
|
863
891
|
* @example
|
864
|
-
*
|
865
|
-
*
|
892
|
+
* 0x1122334411223344.lshift64(1).to_s(16) # => "2244668822446688"
|
893
|
+
* 0x1122334411223344.lshift64(2).to_s(16) # => "4488cd104488cd10"
|
866
894
|
*
|
867
895
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
868
896
|
* @return [Integer]
|
869
897
|
*/
|
898
|
+
def_int_method_with_arg(lshift64);
|
899
|
+
|
870
900
|
static VALUE
|
871
901
|
fnum_rshift8(VALUE fnum, VALUE shiftdist)
|
872
902
|
{
|
@@ -874,7 +904,7 @@ fnum_rshift8(VALUE fnum, VALUE shiftdist)
|
|
874
904
|
if (shiftdist == fix_zero)
|
875
905
|
return fnum;
|
876
906
|
else
|
877
|
-
return LONG2FIX((value & ~
|
907
|
+
return LONG2FIX(((ulong)value & ~0xFFUL) | rshift8((uint8_t)value, shiftdist));
|
878
908
|
}
|
879
909
|
|
880
910
|
static VALUE
|
@@ -883,24 +913,25 @@ bnum_rshift8(VALUE bnum, VALUE shiftdist)
|
|
883
913
|
if (shiftdist == fix_zero)
|
884
914
|
return bnum;
|
885
915
|
else
|
886
|
-
return modify_lo8_in_bignum(bnum, rshift8(*RBIGNUM_DIGITS(bnum), shiftdist));
|
916
|
+
return modify_lo8_in_bignum(bnum, rshift8((uint8_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
887
917
|
}
|
888
918
|
|
889
|
-
/* Document-method:
|
890
|
-
*
|
891
|
-
* Right-shift of the low 16 bits in this integer.
|
919
|
+
/* Document-method: Integer#rshift8
|
920
|
+
* Right-shift of the low 8 bits in this integer.
|
892
921
|
*
|
893
922
|
* If the shift distance is negative, a left shift will be performed instead.
|
894
923
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
895
|
-
* more than
|
924
|
+
* more than 7 or less than -7, the low 8 bits will all be zeroed.
|
896
925
|
*
|
897
926
|
* @example
|
898
|
-
* 0x11223344.
|
899
|
-
* 0x11223344.
|
927
|
+
* 0x11223344.rshift8(1).to_s(16) # => "11223322"
|
928
|
+
* 0x11223344.rshift8(2).to_s(16) # => "11223311"
|
900
929
|
*
|
901
930
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
902
931
|
* @return [Integer]
|
903
932
|
*/
|
933
|
+
def_int_method_with_arg(rshift8);
|
934
|
+
|
904
935
|
static VALUE
|
905
936
|
fnum_rshift16(VALUE fnum, VALUE shiftdist)
|
906
937
|
{
|
@@ -908,7 +939,7 @@ fnum_rshift16(VALUE fnum, VALUE shiftdist)
|
|
908
939
|
if (shiftdist == fix_zero)
|
909
940
|
return fnum;
|
910
941
|
else
|
911
|
-
return LONG2FIX((value & ~
|
942
|
+
return LONG2FIX(((ulong)value & ~0xFFFFUL) | rshift16((uint16_t)value, shiftdist));
|
912
943
|
}
|
913
944
|
|
914
945
|
static VALUE
|
@@ -917,24 +948,25 @@ bnum_rshift16(VALUE bnum, VALUE shiftdist)
|
|
917
948
|
if (shiftdist == fix_zero)
|
918
949
|
return bnum;
|
919
950
|
else
|
920
|
-
return modify_lo16_in_bignum(bnum, rshift16(*RBIGNUM_DIGITS(bnum), shiftdist));
|
951
|
+
return modify_lo16_in_bignum(bnum, rshift16((uint16_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
921
952
|
}
|
922
953
|
|
923
|
-
/* Document-method:
|
924
|
-
*
|
925
|
-
* Right-shift of the low 32 bits in this integer.
|
954
|
+
/* Document-method: Integer#rshift16
|
955
|
+
* Right-shift of the low 16 bits in this integer.
|
926
956
|
*
|
927
957
|
* If the shift distance is negative, a left shift will be performed instead.
|
928
958
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
929
|
-
* more than
|
959
|
+
* more than 15 or less than -15, the low 16 bits will all be zeroed.
|
930
960
|
*
|
931
961
|
* @example
|
932
|
-
* 0x11223344.
|
933
|
-
* 0x11223344.
|
962
|
+
* 0x11223344.rshift16(1).to_s(16) # => "112219a2"
|
963
|
+
* 0x11223344.rshift16(2).to_s(16) # => "11220cd1"
|
934
964
|
*
|
935
965
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
936
966
|
* @return [Integer]
|
937
967
|
*/
|
968
|
+
def_int_method_with_arg(rshift16);
|
969
|
+
|
938
970
|
static VALUE
|
939
971
|
fnum_rshift32(VALUE fnum, VALUE shiftdist)
|
940
972
|
{
|
@@ -942,7 +974,7 @@ fnum_rshift32(VALUE fnum, VALUE shiftdist)
|
|
942
974
|
if (shiftdist == fix_zero)
|
943
975
|
return fnum;
|
944
976
|
else
|
945
|
-
return LONG2FIX((value & ~
|
977
|
+
return LONG2FIX(((ulong)value & ~0xFFFFFFFFUL) | rshift32((uint32_t)value, shiftdist));
|
946
978
|
}
|
947
979
|
|
948
980
|
static VALUE
|
@@ -954,21 +986,22 @@ bnum_rshift32(VALUE bnum, VALUE shiftdist)
|
|
954
986
|
return modify_lo32_in_bignum(bnum, rshift32(*RBIGNUM_DIGITS(bnum), shiftdist));
|
955
987
|
}
|
956
988
|
|
957
|
-
/* Document-method:
|
958
|
-
*
|
959
|
-
* Right-shift of the low 64 bits in this integer.
|
989
|
+
/* Document-method: Integer#rshift32
|
990
|
+
* Right-shift of the low 32 bits in this integer.
|
960
991
|
*
|
961
992
|
* If the shift distance is negative, a left shift will be performed instead.
|
962
993
|
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
963
|
-
* more than
|
994
|
+
* more than 31 or less than -31, the low 32 bits will all be zeroed.
|
964
995
|
*
|
965
996
|
* @example
|
966
|
-
*
|
967
|
-
*
|
997
|
+
* 0x11223344.rshift32(1).to_s(16) # => "89119a2"
|
998
|
+
* 0x11223344.rshift32(2).to_s(16) # => "4488cd1"
|
968
999
|
*
|
969
1000
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
970
1001
|
* @return [Integer]
|
971
1002
|
*/
|
1003
|
+
def_int_method_with_arg(rshift32);
|
1004
|
+
|
972
1005
|
static VALUE
|
973
1006
|
fnum_rshift64(VALUE fnum, VALUE shiftdist)
|
974
1007
|
{
|
@@ -993,21 +1026,22 @@ bnum_rshift64(VALUE bnum, VALUE shiftdist)
|
|
993
1026
|
return modify_lo64_in_bignum(bnum, rshift64(load_64_from_bignum(bnum), shiftdist));
|
994
1027
|
}
|
995
1028
|
|
996
|
-
/* Document-method:
|
997
|
-
*
|
998
|
-
* Arithmetic right-shift of the low 8 bits in this integer.
|
1029
|
+
/* Document-method: Integer#rshift64
|
1030
|
+
* Right-shift of the low 64 bits in this integer.
|
999
1031
|
*
|
1000
|
-
* If
|
1001
|
-
*
|
1002
|
-
*
|
1032
|
+
* If the shift distance is negative, a left shift will be performed instead.
|
1033
|
+
* The vacated bit positions will be filled with 0 bits. If shift distance is
|
1034
|
+
* more than 63 or less than -63, the low 64 bits will all be zeroed.
|
1003
1035
|
*
|
1004
1036
|
* @example
|
1005
|
-
*
|
1006
|
-
*
|
1037
|
+
* 0x1122334411223344.rshift64(1).to_s(16) # => "89119a2089119a2"
|
1038
|
+
* 0x1122334411223344.rshift64(2).to_s(16) # => "4488cd104488cd1"
|
1007
1039
|
*
|
1008
1040
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
1009
1041
|
* @return [Integer]
|
1010
1042
|
*/
|
1043
|
+
def_int_method_with_arg(rshift64);
|
1044
|
+
|
1011
1045
|
static VALUE
|
1012
1046
|
fnum_arith_rshift8(VALUE fnum, VALUE shiftdist)
|
1013
1047
|
{
|
@@ -1015,7 +1049,7 @@ fnum_arith_rshift8(VALUE fnum, VALUE shiftdist)
|
|
1015
1049
|
if (shiftdist == fix_zero)
|
1016
1050
|
return fnum;
|
1017
1051
|
else
|
1018
|
-
return LONG2FIX((value & ~0xFFUL) | arith_rshift8(value, shiftdist));
|
1052
|
+
return LONG2FIX(((ulong)value & ~0xFFUL) | arith_rshift8((uint8_t)value, shiftdist));
|
1019
1053
|
}
|
1020
1054
|
|
1021
1055
|
static VALUE
|
@@ -1024,24 +1058,25 @@ bnum_arith_rshift8(VALUE bnum, VALUE shiftdist)
|
|
1024
1058
|
if (shiftdist == fix_zero)
|
1025
1059
|
return bnum;
|
1026
1060
|
else
|
1027
|
-
return modify_lo8_in_bignum(bnum, arith_rshift8(*RBIGNUM_DIGITS(bnum), shiftdist));
|
1061
|
+
return modify_lo8_in_bignum(bnum, arith_rshift8((uint8_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
1028
1062
|
}
|
1029
1063
|
|
1030
|
-
/* Document-method:
|
1031
|
-
*
|
1032
|
-
* Arithmetic right-shift of the low 16 bits in this integer.
|
1064
|
+
/* Document-method: Integer#arith_rshift8
|
1065
|
+
* Arithmetic right-shift of the low 8 bits in this integer.
|
1033
1066
|
*
|
1034
|
-
* If bit
|
1067
|
+
* If bit 8 is a 1, the vacated bit positions will be filled with 1s. Otherwise,
|
1035
1068
|
* they will be filled with 0s. Or, if the shift distance is negative, a left shift
|
1036
1069
|
* will be performed instead, and the vacated bit positions will be filled with 0s.
|
1037
1070
|
*
|
1038
1071
|
* @example
|
1039
|
-
* 0xaabbccdd.
|
1040
|
-
* 0xaabbccdd.
|
1072
|
+
* 0xaabbccdd.arith_rshift8(1).to_s(16) # => "aabbccee"
|
1073
|
+
* 0xaabbccdd.arith_rshift8(2).to_s(16) # => "aabbccf7"
|
1041
1074
|
*
|
1042
1075
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
1043
1076
|
* @return [Integer]
|
1044
1077
|
*/
|
1078
|
+
def_int_method_with_arg(arith_rshift8);
|
1079
|
+
|
1045
1080
|
static VALUE
|
1046
1081
|
fnum_arith_rshift16(VALUE fnum, VALUE shiftdist)
|
1047
1082
|
{
|
@@ -1049,7 +1084,7 @@ fnum_arith_rshift16(VALUE fnum, VALUE shiftdist)
|
|
1049
1084
|
if (shiftdist == fix_zero)
|
1050
1085
|
return fnum;
|
1051
1086
|
else
|
1052
|
-
return LONG2FIX((value & ~0xFFFFUL) | arith_rshift16(value, shiftdist));
|
1087
|
+
return LONG2FIX(((ulong)value & ~0xFFFFUL) | arith_rshift16((uint16_t)value, shiftdist));
|
1053
1088
|
}
|
1054
1089
|
|
1055
1090
|
static VALUE
|
@@ -1058,24 +1093,25 @@ bnum_arith_rshift16(VALUE bnum, VALUE shiftdist)
|
|
1058
1093
|
if (shiftdist == fix_zero)
|
1059
1094
|
return bnum;
|
1060
1095
|
else
|
1061
|
-
return modify_lo16_in_bignum(bnum, arith_rshift16(*RBIGNUM_DIGITS(bnum), shiftdist));
|
1096
|
+
return modify_lo16_in_bignum(bnum, arith_rshift16((uint16_t)*RBIGNUM_DIGITS(bnum), shiftdist));
|
1062
1097
|
}
|
1063
1098
|
|
1064
|
-
/* Document-method:
|
1065
|
-
*
|
1066
|
-
* Arithmetic right-shift of the low 32 bits in this integer.
|
1099
|
+
/* Document-method: Integer#arith_rshift16
|
1100
|
+
* Arithmetic right-shift of the low 16 bits in this integer.
|
1067
1101
|
*
|
1068
|
-
* If bit
|
1102
|
+
* If bit 16 is a 1, the vacated bit positions will be filled with 1s. Otherwise,
|
1069
1103
|
* they will be filled with 0s. Or, if the shift distance is negative, a left shift
|
1070
1104
|
* will be performed instead, and the vacated bit positions will be filled with 0s.
|
1071
1105
|
*
|
1072
1106
|
* @example
|
1073
|
-
*
|
1074
|
-
*
|
1107
|
+
* 0xaabbccdd.arith_rshift16(1).to_s(16) # => "aabbe66e"
|
1108
|
+
* 0xaabbccdd.arith_rshift16(2).to_s(16) # => "aabbf337"
|
1075
1109
|
*
|
1076
1110
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
1077
1111
|
* @return [Integer]
|
1078
1112
|
*/
|
1113
|
+
def_int_method_with_arg(arith_rshift16);
|
1114
|
+
|
1079
1115
|
static VALUE
|
1080
1116
|
fnum_arith_rshift32(VALUE fnum, VALUE shiftdist)
|
1081
1117
|
{
|
@@ -1083,7 +1119,7 @@ fnum_arith_rshift32(VALUE fnum, VALUE shiftdist)
|
|
1083
1119
|
if (shiftdist == fix_zero)
|
1084
1120
|
return fnum;
|
1085
1121
|
else
|
1086
|
-
return LONG2FIX((value & ~0xFFFFFFFFUL) | arith_rshift32(value, shiftdist));
|
1122
|
+
return LONG2FIX(((ulong)value & ~0xFFFFFFFFUL) | arith_rshift32((uint32_t)value, shiftdist));
|
1087
1123
|
}
|
1088
1124
|
|
1089
1125
|
static VALUE
|
@@ -1095,28 +1131,29 @@ bnum_arith_rshift32(VALUE bnum, VALUE shiftdist)
|
|
1095
1131
|
return modify_lo32_in_bignum(bnum, arith_rshift32(*RBIGNUM_DIGITS(bnum), shiftdist));
|
1096
1132
|
}
|
1097
1133
|
|
1098
|
-
/* Document-method:
|
1099
|
-
*
|
1100
|
-
* Arithmetic right-shift of the low 64 bits in this integer.
|
1134
|
+
/* Document-method: Integer#arith_rshift32
|
1135
|
+
* Arithmetic right-shift of the low 32 bits in this integer.
|
1101
1136
|
*
|
1102
|
-
* If bit
|
1137
|
+
* If bit 32 is a 1, the vacated bit positions will be filled with 1s. Otherwise,
|
1103
1138
|
* they will be filled with 0s. Or, if the shift distance is negative, a left shift
|
1104
1139
|
* will be performed instead, and the vacated bit positions will be filled with 0s.
|
1105
1140
|
*
|
1106
1141
|
* @example
|
1107
|
-
* 0xaabbccddaabbccdd.
|
1108
|
-
* 0xaabbccddaabbccdd.
|
1142
|
+
* 0xaabbccddaabbccdd.arith_rshift32(1).to_s(16) # => "d55de66e"
|
1143
|
+
* 0xaabbccddaabbccdd.arith_rshift32(2).to_s(16) # => "eaaef337"
|
1109
1144
|
*
|
1110
1145
|
* @param shiftdist [Integer] Number of bit positions to shift by
|
1111
1146
|
* @return [Integer]
|
1112
1147
|
*/
|
1148
|
+
def_int_method_with_arg(arith_rshift32);
|
1149
|
+
|
1113
1150
|
static VALUE
|
1114
1151
|
fnum_arith_rshift64(VALUE fnum, VALUE shiftdist)
|
1115
1152
|
{
|
1116
1153
|
if (shiftdist == fix_zero)
|
1117
1154
|
return fnum;
|
1118
1155
|
else
|
1119
|
-
return ULONG2NUM(arith_rshift64(FIX2LONG(fnum), shiftdist));
|
1156
|
+
return ULONG2NUM(arith_rshift64((uint64_t)FIX2LONG(fnum), shiftdist));
|
1120
1157
|
}
|
1121
1158
|
|
1122
1159
|
static VALUE
|
@@ -1128,6 +1165,22 @@ bnum_arith_rshift64(VALUE bnum, VALUE shiftdist)
|
|
1128
1165
|
return modify_lo64_in_bignum(bnum, arith_rshift64(load_64_from_bignum(bnum), shiftdist));
|
1129
1166
|
}
|
1130
1167
|
|
1168
|
+
/* Document-method: Integer#arith_rshift64
|
1169
|
+
* Arithmetic right-shift of the low 64 bits in this integer.
|
1170
|
+
*
|
1171
|
+
* If bit 64 is a 1, the vacated bit positions will be filled with 1s. Otherwise,
|
1172
|
+
* they will be filled with 0s. Or, if the shift distance is negative, a left shift
|
1173
|
+
* will be performed instead, and the vacated bit positions will be filled with 0s.
|
1174
|
+
*
|
1175
|
+
* @example
|
1176
|
+
* 0xaabbccddaabbccdd.arith_rshift64(1).to_s(16) # => "d55de66ed55de66e"
|
1177
|
+
* 0xaabbccddaabbccdd.arith_rshift64(2).to_s(16) # => "eaaef3376aaef337"
|
1178
|
+
*
|
1179
|
+
* @param shiftdist [Integer] Number of bit positions to shift by
|
1180
|
+
* @return [Integer]
|
1181
|
+
*/
|
1182
|
+
def_int_method_with_arg(arith_rshift64);
|
1183
|
+
|
1131
1184
|
static const uint8_t bitreverse_table[] =
|
1132
1185
|
{
|
1133
1186
|
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
@@ -1154,7 +1207,7 @@ static inline uint8_t reverse8(uint8_t value)
|
|
1154
1207
|
/* 64-bit CPU
|
1155
1208
|
* Thanks to the Bit Twiddling Hacks page:
|
1156
1209
|
* http://graphics.stanford.edu/~seander/bithacks.html */
|
1157
|
-
return (value * 0x0202020202UL & 0x010884422010UL) % 1023;
|
1210
|
+
return (uint8_t)((value * 0x0202020202UL & 0x010884422010UL) % 1023);
|
1158
1211
|
else
|
1159
1212
|
/* 32-bit CPU */
|
1160
1213
|
return bitreverse_table[value];
|
@@ -1162,37 +1215,26 @@ static inline uint8_t reverse8(uint8_t value)
|
|
1162
1215
|
|
1163
1216
|
static inline uint16_t reverse16(uint16_t value)
|
1164
1217
|
{
|
1165
|
-
return (bitreverse_table[value & 0xFF] << 8) | bitreverse_table[value >> 8];
|
1218
|
+
return (uint16_t)(bitreverse_table[value & 0xFF] << 8) | bitreverse_table[value >> 8];
|
1166
1219
|
}
|
1167
1220
|
|
1168
1221
|
static inline uint32_t reverse32(uint32_t value)
|
1169
1222
|
{
|
1170
|
-
return ((uint32_t)reverse16(value) << 16) | reverse16(value >> 16);
|
1223
|
+
return ((uint32_t)reverse16((uint16_t)value) << 16) | reverse16(value >> 16);
|
1171
1224
|
}
|
1172
1225
|
|
1173
1226
|
static inline uint64_t reverse64(uint64_t value)
|
1174
1227
|
{
|
1175
|
-
return ((uint64_t)reverse32(value) << 32) | reverse32(value >> 32);
|
1228
|
+
return ((uint64_t)reverse32((uint32_t)value) << 32) | reverse32(value >> 32);
|
1176
1229
|
}
|
1177
1230
|
|
1178
|
-
/* Document-method: Fixnum#bitreverse8
|
1179
|
-
* Document-method: Bignum#bitreverse8
|
1180
|
-
* Reverse the low 8 bits in this integer.
|
1181
|
-
*
|
1182
|
-
* If the receiver is negative, raise `RangeError`.
|
1183
|
-
*
|
1184
|
-
* @example
|
1185
|
-
* 0b01101011.bitreverse8.to_s(2) # => "11010110"
|
1186
|
-
*
|
1187
|
-
* @return [Integer]
|
1188
|
-
*/
|
1189
1231
|
static VALUE
|
1190
1232
|
fnum_bitreverse8(VALUE fnum)
|
1191
1233
|
{
|
1192
1234
|
long value = FIX2LONG(fnum);
|
1193
1235
|
if (value < 0)
|
1194
1236
|
rb_raise(rb_eRangeError, "can't reverse bits in a negative number");
|
1195
|
-
return LONG2FIX((value & ~0xFFL) | reverse8(value));
|
1237
|
+
return LONG2FIX((value & ~0xFFL) | reverse8((uint8_t)value));
|
1196
1238
|
}
|
1197
1239
|
|
1198
1240
|
static VALUE
|
@@ -1200,27 +1242,28 @@ bnum_bitreverse8(VALUE bnum)
|
|
1200
1242
|
{
|
1201
1243
|
if (RBIGNUM_NEGATIVE_P(bnum))
|
1202
1244
|
rb_raise(rb_eRangeError, "can't reverse bits in a negative number");
|
1203
|
-
return modify_lo8_in_bignum(bnum, reverse8(*RBIGNUM_DIGITS(bnum)));
|
1245
|
+
return modify_lo8_in_bignum(bnum, reverse8((uint8_t)*RBIGNUM_DIGITS(bnum)));
|
1204
1246
|
}
|
1205
1247
|
|
1206
|
-
/* Document-method:
|
1207
|
-
*
|
1208
|
-
* Reverse the low 16 bits in this integer.
|
1248
|
+
/* Document-method: Integer#bitreverse8
|
1249
|
+
* Reverse the low 8 bits in this integer.
|
1209
1250
|
*
|
1210
1251
|
* If the receiver is negative, raise `RangeError`.
|
1211
1252
|
*
|
1212
1253
|
* @example
|
1213
|
-
*
|
1254
|
+
* 0b01101011.bitreverse8.to_s(2) # => "11010110"
|
1214
1255
|
*
|
1215
1256
|
* @return [Integer]
|
1216
1257
|
*/
|
1258
|
+
def_int_method(bitreverse8);
|
1259
|
+
|
1217
1260
|
static VALUE
|
1218
1261
|
fnum_bitreverse16(VALUE fnum)
|
1219
1262
|
{
|
1220
1263
|
long value = FIX2LONG(fnum);
|
1221
1264
|
if (value < 0)
|
1222
1265
|
rb_raise(rb_eRangeError, "can't reverse bits in a negative number");
|
1223
|
-
return LONG2FIX((value & ~0xFFFFL) | reverse16(value));
|
1266
|
+
return LONG2FIX((value & ~0xFFFFL) | reverse16((uint16_t)value));
|
1224
1267
|
}
|
1225
1268
|
|
1226
1269
|
static VALUE
|
@@ -1228,25 +1271,26 @@ bnum_bitreverse16(VALUE bnum)
|
|
1228
1271
|
{
|
1229
1272
|
if (RBIGNUM_NEGATIVE_P(bnum))
|
1230
1273
|
rb_raise(rb_eRangeError, "can't reverse bits in a negative number");
|
1231
|
-
return modify_lo16_in_bignum(bnum, reverse16(*RBIGNUM_DIGITS(bnum)));
|
1274
|
+
return modify_lo16_in_bignum(bnum, reverse16((uint16_t)*RBIGNUM_DIGITS(bnum)));
|
1232
1275
|
}
|
1233
1276
|
|
1234
|
-
/* Document-method:
|
1235
|
-
*
|
1236
|
-
* Reverse the low 32 bits in this integer.
|
1277
|
+
/* Document-method: Integer#bitreverse16
|
1278
|
+
* Reverse the low 16 bits in this integer.
|
1237
1279
|
*
|
1238
1280
|
* If the receiver is negative, raise `RangeError`.
|
1239
1281
|
*
|
1240
1282
|
* @example
|
1241
|
-
*
|
1283
|
+
* 0b0110101100001011.bitreverse16.to_s(2) # => "1101000011010110"
|
1242
1284
|
*
|
1243
1285
|
* @return [Integer]
|
1244
1286
|
*/
|
1287
|
+
def_int_method(bitreverse16);
|
1288
|
+
|
1245
1289
|
static VALUE
|
1246
1290
|
fnum_bitreverse32(VALUE fnum)
|
1247
1291
|
{
|
1248
1292
|
long value = FIX2LONG(fnum);
|
1249
|
-
uint32_t lo32 = value;
|
1293
|
+
uint32_t lo32 = (uint32_t)value;
|
1250
1294
|
if (value < 0)
|
1251
1295
|
rb_raise(rb_eRangeError, "can't reverse bits in a negative number");
|
1252
1296
|
else if (SIZEOF_LONG == 4)
|
@@ -1263,24 +1307,25 @@ bnum_bitreverse32(VALUE bnum)
|
|
1263
1307
|
return modify_lo32_in_bignum(bnum, reverse32(*RBIGNUM_DIGITS(bnum)));
|
1264
1308
|
}
|
1265
1309
|
|
1266
|
-
/* Document-method:
|
1267
|
-
*
|
1268
|
-
* Reverse the low 64 bits in this integer.
|
1310
|
+
/* Document-method: Integer#bitreverse32
|
1311
|
+
* Reverse the low 32 bits in this integer.
|
1269
1312
|
*
|
1270
1313
|
* If the receiver is negative, raise `RangeError`.
|
1271
1314
|
*
|
1272
1315
|
* @example
|
1273
|
-
*
|
1316
|
+
* 0x12341234.bitreverse32.to_s(16) # => "2c482c48"
|
1274
1317
|
*
|
1275
1318
|
* @return [Integer]
|
1276
1319
|
*/
|
1320
|
+
def_int_method(bitreverse32);
|
1321
|
+
|
1277
1322
|
static VALUE
|
1278
1323
|
fnum_bitreverse64(VALUE fnum)
|
1279
1324
|
{
|
1280
1325
|
long value = FIX2LONG(fnum);
|
1281
1326
|
if (value < 0)
|
1282
1327
|
rb_raise(rb_eRangeError, "can't reverse bits in a negative number");
|
1283
|
-
return ULL2NUM(reverse64(value));
|
1328
|
+
return ULL2NUM(reverse64((uint64_t)value));
|
1284
1329
|
}
|
1285
1330
|
|
1286
1331
|
static VALUE
|
@@ -1291,80 +1336,78 @@ bnum_bitreverse64(VALUE bnum)
|
|
1291
1336
|
return modify_lo64_in_bignum(bnum, reverse64(load_64_from_bignum(bnum)));
|
1292
1337
|
}
|
1293
1338
|
|
1294
|
-
/*
|
1295
|
-
|
1296
|
-
|
1339
|
+
/* Document-method: Integer#bitreverse64
|
1340
|
+
* Reverse the low 64 bits in this integer.
|
1341
|
+
*
|
1342
|
+
* If the receiver is negative, raise `RangeError`.
|
1343
|
+
*
|
1344
|
+
* @example
|
1345
|
+
* 0xabcd1234abcd1234.bitreverse64.to_s(16) # => "2c48b3d52c48b3d5"
|
1346
|
+
*
|
1347
|
+
* @return [Integer]
|
1348
|
+
*/
|
1349
|
+
def_int_method(bitreverse64);
|
1350
|
+
|
1351
|
+
/* Document-class: Integer
|
1352
|
+
* Ruby's good old Integer.
|
1353
|
+
*
|
1354
|
+
* `require "bit-twiddle/core_ext"` before trying to use any of the below methods.
|
1355
|
+
*/
|
1356
|
+
/* Document-class: String
|
1357
|
+
* Ruby's good old String.
|
1358
|
+
*
|
1359
|
+
* `require "bit-twiddle/core_ext"` before trying to use any of the below methods.
|
1360
|
+
*/
|
1361
|
+
|
1362
|
+
/* Add all `bit-twiddle` methods directly to `Integer`. */
|
1363
|
+
static void init_core_extensions()
|
1297
1364
|
{
|
1298
|
-
rb_define_method(
|
1299
|
-
rb_define_method(rb_cBignum, "popcount", bnum_popcount, 0);
|
1365
|
+
rb_define_method(rb_cInteger, "popcount", int_popcount, 0);
|
1300
1366
|
rb_define_method(rb_cString, "popcount", str_popcount, 0);
|
1301
1367
|
|
1302
|
-
rb_define_method(
|
1303
|
-
rb_define_method(
|
1304
|
-
|
1305
|
-
rb_define_method(
|
1306
|
-
|
1307
|
-
rb_define_method(
|
1308
|
-
|
1309
|
-
rb_define_method(
|
1310
|
-
rb_define_method(
|
1311
|
-
rb_define_method(
|
1312
|
-
rb_define_method(
|
1313
|
-
|
1314
|
-
rb_define_method(
|
1315
|
-
rb_define_method(
|
1316
|
-
rb_define_method(
|
1317
|
-
rb_define_method(
|
1318
|
-
|
1319
|
-
rb_define_method(
|
1320
|
-
rb_define_method(
|
1321
|
-
rb_define_method(
|
1322
|
-
|
1323
|
-
|
1324
|
-
rb_define_method(
|
1325
|
-
rb_define_method(
|
1326
|
-
rb_define_method(
|
1327
|
-
rb_define_method(
|
1328
|
-
rb_define_method(rb_cBignum, "lrot32", bnum_lrot32, 1);
|
1329
|
-
rb_define_method(rb_cFixnum, "lrot64", fnum_lrot64, 1);
|
1330
|
-
rb_define_method(rb_cBignum, "lrot64", bnum_lrot64, 1);
|
1331
|
-
|
1332
|
-
rb_define_method(rb_cFixnum, "lshift8", fnum_lshift8, 1);
|
1333
|
-
rb_define_method(rb_cBignum, "lshift8", bnum_lshift8, 1);
|
1334
|
-
rb_define_method(rb_cFixnum, "lshift16", fnum_lshift16, 1);
|
1335
|
-
rb_define_method(rb_cBignum, "lshift16", bnum_lshift16, 1);
|
1336
|
-
rb_define_method(rb_cFixnum, "lshift32", fnum_lshift32, 1);
|
1337
|
-
rb_define_method(rb_cBignum, "lshift32", bnum_lshift32, 1);
|
1338
|
-
rb_define_method(rb_cFixnum, "lshift64", fnum_lshift64, 1);
|
1339
|
-
rb_define_method(rb_cBignum, "lshift64", bnum_lshift64, 1);
|
1340
|
-
|
1341
|
-
rb_define_method(rb_cFixnum, "rshift8", fnum_rshift8, 1);
|
1342
|
-
rb_define_method(rb_cBignum, "rshift8", bnum_rshift8, 1);
|
1343
|
-
rb_define_method(rb_cFixnum, "rshift16", fnum_rshift16, 1);
|
1344
|
-
rb_define_method(rb_cBignum, "rshift16", bnum_rshift16, 1);
|
1345
|
-
rb_define_method(rb_cFixnum, "rshift32", fnum_rshift32, 1);
|
1346
|
-
rb_define_method(rb_cBignum, "rshift32", bnum_rshift32, 1);
|
1347
|
-
rb_define_method(rb_cFixnum, "rshift64", fnum_rshift64, 1);
|
1348
|
-
rb_define_method(rb_cBignum, "rshift64", bnum_rshift64, 1);
|
1349
|
-
|
1350
|
-
rb_define_method(rb_cFixnum, "arith_rshift8", fnum_arith_rshift8, 1);
|
1351
|
-
rb_define_method(rb_cBignum, "arith_rshift8", bnum_arith_rshift8, 1);
|
1352
|
-
rb_define_method(rb_cFixnum, "arith_rshift16", fnum_arith_rshift16, 1);
|
1353
|
-
rb_define_method(rb_cBignum, "arith_rshift16", bnum_arith_rshift16, 1);
|
1354
|
-
rb_define_method(rb_cFixnum, "arith_rshift32", fnum_arith_rshift32, 1);
|
1355
|
-
rb_define_method(rb_cBignum, "arith_rshift32", bnum_arith_rshift32, 1);
|
1356
|
-
rb_define_method(rb_cFixnum, "arith_rshift64", fnum_arith_rshift64, 1);
|
1357
|
-
rb_define_method(rb_cBignum, "arith_rshift64", bnum_arith_rshift64, 1);
|
1358
|
-
|
1359
|
-
rb_define_method(rb_cFixnum, "bitreverse8", fnum_bitreverse8, 0);
|
1360
|
-
rb_define_method(rb_cBignum, "bitreverse8", bnum_bitreverse8, 0);
|
1361
|
-
rb_define_method(rb_cFixnum, "bitreverse16", fnum_bitreverse16, 0);
|
1362
|
-
rb_define_method(rb_cBignum, "bitreverse16", bnum_bitreverse16, 0);
|
1363
|
-
rb_define_method(rb_cFixnum, "bitreverse32", fnum_bitreverse32, 0);
|
1364
|
-
rb_define_method(rb_cBignum, "bitreverse32", bnum_bitreverse32, 0);
|
1365
|
-
rb_define_method(rb_cFixnum, "bitreverse64", fnum_bitreverse64, 0);
|
1366
|
-
rb_define_method(rb_cBignum, "bitreverse64", bnum_bitreverse64, 0);
|
1368
|
+
rb_define_method(rb_cInteger, "lo_bit", int_lo_bit, 0);
|
1369
|
+
rb_define_method(rb_cInteger, "hi_bit", int_hi_bit, 0);
|
1370
|
+
|
1371
|
+
rb_define_method(rb_cInteger, "bswap16", int_bswap16, 0);
|
1372
|
+
rb_define_method(rb_cInteger, "bswap32", int_bswap32, 0);
|
1373
|
+
rb_define_method(rb_cInteger, "bswap64", int_bswap64, 0);
|
1374
|
+
|
1375
|
+
rb_define_method(rb_cInteger, "rrot8", int_rrot8, 1);
|
1376
|
+
rb_define_method(rb_cInteger, "rrot16", int_rrot16, 1);
|
1377
|
+
rb_define_method(rb_cInteger, "rrot32", int_rrot32, 1);
|
1378
|
+
rb_define_method(rb_cInteger, "rrot64", int_rrot64, 1);
|
1379
|
+
|
1380
|
+
rb_define_method(rb_cInteger, "lrot8", int_lrot8, 1);
|
1381
|
+
rb_define_method(rb_cInteger, "lrot16", int_lrot16, 1);
|
1382
|
+
rb_define_method(rb_cInteger, "lrot32", int_lrot32, 1);
|
1383
|
+
rb_define_method(rb_cInteger, "lrot64", int_lrot64, 1);
|
1384
|
+
|
1385
|
+
rb_define_method(rb_cInteger, "lshift8", int_lshift8, 1);
|
1386
|
+
rb_define_method(rb_cInteger, "lshift16", int_lshift16, 1);
|
1387
|
+
rb_define_method(rb_cInteger, "lshift32", int_lshift32, 1);
|
1388
|
+
rb_define_method(rb_cInteger, "lshift64", int_lshift64, 1);
|
1389
|
+
|
1390
|
+
rb_define_method(rb_cInteger, "rshift8", int_rshift8, 1);
|
1391
|
+
rb_define_method(rb_cInteger, "rshift16", int_rshift16, 1);
|
1392
|
+
rb_define_method(rb_cInteger, "rshift32", int_rshift32, 1);
|
1393
|
+
rb_define_method(rb_cInteger, "rshift64", int_rshift64, 1);
|
1367
1394
|
|
1395
|
+
rb_define_method(rb_cInteger, "arith_rshift8", int_arith_rshift8, 1);
|
1396
|
+
rb_define_method(rb_cInteger, "arith_rshift16", int_arith_rshift16, 1);
|
1397
|
+
rb_define_method(rb_cInteger, "arith_rshift32", int_arith_rshift32, 1);
|
1398
|
+
rb_define_method(rb_cInteger, "arith_rshift64", int_arith_rshift64, 1);
|
1399
|
+
|
1400
|
+
rb_define_method(rb_cInteger, "bitreverse8", int_bitreverse8, 0);
|
1401
|
+
rb_define_method(rb_cInteger, "bitreverse16", int_bitreverse16, 0);
|
1402
|
+
rb_define_method(rb_cInteger, "bitreverse32", int_bitreverse32, 0);
|
1403
|
+
rb_define_method(rb_cInteger, "bitreverse64", int_bitreverse64, 0);
|
1404
|
+
}
|
1405
|
+
|
1406
|
+
static VALUE
|
1407
|
+
bt_add_core_extensions(VALUE self)
|
1408
|
+
{
|
1409
|
+
/* this is so Yardoc can find method definitions */
|
1410
|
+
init_core_extensions();
|
1368
1411
|
return Qnil;
|
1369
1412
|
}
|
1370
1413
|
|
@@ -1421,21 +1464,6 @@ def_wrapper(bitreverse16);
|
|
1421
1464
|
def_wrapper(bitreverse32);
|
1422
1465
|
def_wrapper(bitreverse64);
|
1423
1466
|
|
1424
|
-
/* Document-class: Fixnum
|
1425
|
-
* Ruby's good old Fixnum.
|
1426
|
-
*
|
1427
|
-
* `require "bit-twiddle/core_ext"` before trying to use any of the below methods.
|
1428
|
-
*/
|
1429
|
-
/* Document-class: Bignum
|
1430
|
-
* Ruby's good old Bignum.
|
1431
|
-
*
|
1432
|
-
* `require "bit-twiddle/core_ext"` before trying to use any of the below methods.
|
1433
|
-
*/
|
1434
|
-
/* Document-class: String
|
1435
|
-
* Ruby's good old String.
|
1436
|
-
*
|
1437
|
-
* `require "bit-twiddle/core_ext"` before trying to use any of the below methods.
|
1438
|
-
*/
|
1439
1467
|
void Init_bit_twiddle(void)
|
1440
1468
|
{
|
1441
1469
|
VALUE rb_mBitTwiddle = rb_define_module("BitTwiddle");
|
@@ -1450,7 +1478,7 @@ void Init_bit_twiddle(void)
|
|
1450
1478
|
* If `int` is negative, raise `RangeError`.
|
1451
1479
|
*
|
1452
1480
|
* @param int [Integer] The integer to operate on
|
1453
|
-
* @return [
|
1481
|
+
* @return [Integer]
|
1454
1482
|
*/
|
1455
1483
|
rb_define_singleton_method(rb_mBitTwiddle, "popcount", bt_popcount, 1);
|
1456
1484
|
/* Return the index of the lowest 1 bit, where the least-significant bit is index 1.
|
@@ -1462,7 +1490,7 @@ void Init_bit_twiddle(void)
|
|
1462
1490
|
* If `int` is negative, raise `RangeError`.
|
1463
1491
|
*
|
1464
1492
|
* @param int [Integer] The integer to operate on
|
1465
|
-
* @return [
|
1493
|
+
* @return [Integer]
|
1466
1494
|
*/
|
1467
1495
|
rb_define_singleton_method(rb_mBitTwiddle, "lo_bit", bt_lo_bit, 1);
|
1468
1496
|
/* Return the index of the highest 1 bit, where the least-significant bit is index 1.
|
@@ -1474,7 +1502,7 @@ void Init_bit_twiddle(void)
|
|
1474
1502
|
* If `int` is negative, raise `RangeError`.
|
1475
1503
|
*
|
1476
1504
|
* @param int [Integer] The integer to operate on
|
1477
|
-
* @return [
|
1505
|
+
* @return [Integer]
|
1478
1506
|
*/
|
1479
1507
|
rb_define_singleton_method(rb_mBitTwiddle, "hi_bit", bt_hi_bit, 1);
|
1480
1508
|
/* Reverse the least-significant and second least-significant bytes of `int`.
|
@@ -1848,79 +1876,4 @@ void Init_bit_twiddle(void)
|
|
1848
1876
|
* @return [Integer]
|
1849
1877
|
*/
|
1850
1878
|
rb_define_singleton_method(rb_mBitTwiddle, "bitreverse64", bt_bitreverse64, 1);
|
1851
|
-
|
1852
|
-
#if 0
|
1853
|
-
/* The following definitions are executed only on BitTwiddle.add_core_extensions
|
1854
|
-
* This is a hack for Yardoc -- so Yardoc can find them: */
|
1855
|
-
|
1856
|
-
rb_define_method(rb_cFixnum, "popcount", fnum_popcount, 0);
|
1857
|
-
rb_define_method(rb_cBignum, "popcount", bnum_popcount, 0);
|
1858
|
-
rb_define_method(rb_cString, "popcount", str_popcount, 0);
|
1859
|
-
|
1860
|
-
rb_define_method(rb_cFixnum, "lo_bit", fnum_lo_bit, 0);
|
1861
|
-
rb_define_method(rb_cBignum, "lo_bit", bnum_lo_bit, 0);
|
1862
|
-
rb_define_method(rb_cFixnum, "hi_bit", fnum_hi_bit, 0);
|
1863
|
-
rb_define_method(rb_cBignum, "hi_bit", bnum_hi_bit, 0);
|
1864
|
-
|
1865
|
-
rb_define_method(rb_cFixnum, "bswap16", fnum_bswap16, 0);
|
1866
|
-
rb_define_method(rb_cBignum, "bswap16", bnum_bswap16, 0);
|
1867
|
-
rb_define_method(rb_cFixnum, "bswap32", fnum_bswap32, 0);
|
1868
|
-
rb_define_method(rb_cBignum, "bswap32", bnum_bswap32, 0);
|
1869
|
-
rb_define_method(rb_cFixnum, "bswap64", fnum_bswap64, 0);
|
1870
|
-
rb_define_method(rb_cBignum, "bswap64", bnum_bswap64, 0);
|
1871
|
-
|
1872
|
-
rb_define_method(rb_cFixnum, "rrot8", fnum_rrot8, 1);
|
1873
|
-
rb_define_method(rb_cBignum, "rrot8", bnum_rrot8, 1);
|
1874
|
-
rb_define_method(rb_cFixnum, "rrot16", fnum_rrot16, 1);
|
1875
|
-
rb_define_method(rb_cBignum, "rrot16", bnum_rrot16, 1);
|
1876
|
-
rb_define_method(rb_cFixnum, "rrot32", fnum_rrot32, 1);
|
1877
|
-
rb_define_method(rb_cBignum, "rrot32", bnum_rrot32, 1);
|
1878
|
-
rb_define_method(rb_cFixnum, "rrot64", fnum_rrot64, 1);
|
1879
|
-
rb_define_method(rb_cBignum, "rrot64", bnum_rrot64, 1);
|
1880
|
-
|
1881
|
-
rb_define_method(rb_cFixnum, "lrot8", fnum_lrot8, 1);
|
1882
|
-
rb_define_method(rb_cBignum, "lrot8", bnum_lrot8, 1);
|
1883
|
-
rb_define_method(rb_cFixnum, "lrot16", fnum_lrot16, 1);
|
1884
|
-
rb_define_method(rb_cBignum, "lrot16", bnum_lrot16, 1);
|
1885
|
-
rb_define_method(rb_cFixnum, "lrot32", fnum_lrot32, 1);
|
1886
|
-
rb_define_method(rb_cBignum, "lrot32", bnum_lrot32, 1);
|
1887
|
-
rb_define_method(rb_cFixnum, "lrot64", fnum_lrot64, 1);
|
1888
|
-
rb_define_method(rb_cBignum, "lrot64", bnum_lrot64, 1);
|
1889
|
-
|
1890
|
-
rb_define_method(rb_cFixnum, "lshift8", fnum_lshift8, 1);
|
1891
|
-
rb_define_method(rb_cBignum, "lshift8", bnum_lshift8, 1);
|
1892
|
-
rb_define_method(rb_cFixnum, "lshift16", fnum_lshift16, 1);
|
1893
|
-
rb_define_method(rb_cBignum, "lshift16", bnum_lshift16, 1);
|
1894
|
-
rb_define_method(rb_cFixnum, "lshift32", fnum_lshift32, 1);
|
1895
|
-
rb_define_method(rb_cBignum, "lshift32", bnum_lshift32, 1);
|
1896
|
-
rb_define_method(rb_cFixnum, "lshift64", fnum_lshift64, 1);
|
1897
|
-
rb_define_method(rb_cBignum, "lshift64", bnum_lshift64, 1);
|
1898
|
-
|
1899
|
-
rb_define_method(rb_cFixnum, "rshift8", fnum_rshift8, 1);
|
1900
|
-
rb_define_method(rb_cBignum, "rshift8", bnum_rshift8, 1);
|
1901
|
-
rb_define_method(rb_cFixnum, "rshift16", fnum_rshift16, 1);
|
1902
|
-
rb_define_method(rb_cBignum, "rshift16", bnum_rshift16, 1);
|
1903
|
-
rb_define_method(rb_cFixnum, "rshift32", fnum_rshift32, 1);
|
1904
|
-
rb_define_method(rb_cBignum, "rshift32", bnum_rshift32, 1);
|
1905
|
-
rb_define_method(rb_cFixnum, "rshift64", fnum_rshift64, 1);
|
1906
|
-
rb_define_method(rb_cBignum, "rshift64", bnum_rshift64, 1);
|
1907
|
-
|
1908
|
-
rb_define_method(rb_cFixnum, "arith_rshift8", fnum_arith_rshift8, 1);
|
1909
|
-
rb_define_method(rb_cBignum, "arith_rshift8", bnum_arith_rshift8, 1);
|
1910
|
-
rb_define_method(rb_cFixnum, "arith_rshift16", fnum_arith_rshift16, 1);
|
1911
|
-
rb_define_method(rb_cBignum, "arith_rshift16", bnum_arith_rshift16, 1);
|
1912
|
-
rb_define_method(rb_cFixnum, "arith_rshift32", fnum_arith_rshift32, 1);
|
1913
|
-
rb_define_method(rb_cBignum, "arith_rshift32", bnum_arith_rshift32, 1);
|
1914
|
-
rb_define_method(rb_cFixnum, "arith_rshift64", fnum_arith_rshift64, 1);
|
1915
|
-
rb_define_method(rb_cBignum, "arith_rshift64", bnum_arith_rshift64, 1);
|
1916
|
-
|
1917
|
-
rb_define_method(rb_cFixnum, "bitreverse8", fnum_bitreverse8, 0);
|
1918
|
-
rb_define_method(rb_cBignum, "bitreverse8", bnum_bitreverse8, 0);
|
1919
|
-
rb_define_method(rb_cFixnum, "bitreverse16", fnum_bitreverse16, 0);
|
1920
|
-
rb_define_method(rb_cBignum, "bitreverse16", bnum_bitreverse16, 0);
|
1921
|
-
rb_define_method(rb_cFixnum, "bitreverse32", fnum_bitreverse32, 0);
|
1922
|
-
rb_define_method(rb_cBignum, "bitreverse32", bnum_bitreverse32, 0);
|
1923
|
-
rb_define_method(rb_cFixnum, "bitreverse64", fnum_bitreverse64, 0);
|
1924
|
-
rb_define_method(rb_cBignum, "bitreverse64", bnum_bitreverse64, 0);
|
1925
|
-
#endif
|
1926
1879
|
}
|