overflow 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: da45bcd93d214011fe0426b29f28127b9db55af8
4
- data.tar.gz: ab817a7f4ccfbe748cb8911ed5ce11acd0d37c86
3
+ metadata.gz: 833a4630a30e7f8723e782791f9ab23b165a06e7
4
+ data.tar.gz: 449f416ff31101f37f2a320a72db5d6cf5cbe1b9
5
5
  SHA512:
6
- metadata.gz: 94ab24a96c978d9f1d556109114b2177fdcd9c9ba84c24a23d23dde617b7db169ad516419a197fe7e254724595c1b8cec426b55fa7ee087b008d974b5f2fb9a9
7
- data.tar.gz: 22cc6db2db596113391d75120589109e96b201361cdc02cb558f17063248ea62e93f61da1798b0ab0495543b236845cad1f2896dd246e1413e26b151cbb333ac
6
+ metadata.gz: d895399c9ce7b662012efc2421bcb0618cba2a4d5eeb49cb23b3ed7efbb886e016311968ee05e5275ff9ea4edcf9cf9ff97ce98d33246a3e29ac7bff8784f2b8
7
+ data.tar.gz: b6ffe5f740632d821c863d07a01963d42f43559f3eb486c26325c2d43dca6aab429fb5f9cec2e284cb7a47c7d992c7b0a6c18d64e18a6b8f0b45d7764ded48c6
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Overflow
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/overflow.png)](http://badge.fury.io/rb/overflow)
4
+ [![Build Status](https://travis-ci.org/ksss/overflow.png?branch=master)](https://travis-ci.org/ksss/overflow)
5
+
3
6
  Overflow is a class to overflow calculated as C language in Ruby.
4
7
 
5
8
  ## Usage
@@ -7,43 +10,84 @@ Overflow is a class to overflow calculated as C language in Ruby.
7
10
  ```ruby
8
11
  require 'overflow'
9
12
 
10
- def murmur_hash str
11
- data = str.dup.unpack("C*")
12
- m = 0x5bd1e995
13
- r = 16
14
- length = Overflow.new "C" # "C" mean 32bit unsigned char (same as pack template)
15
- length.set str.bytesize
16
- h = length * m
17
-
18
- while 4 <= length
19
- d = data.shift(4).pack("C*").unpack("I")[0]
20
- h += d # calculate not need `& 0xffffffff`
21
- h *= m
22
- h ^= h >> r
23
- length -= 4
24
- end
25
-
26
- if 2 < length
27
- h += (data[2] << 16) & 0xffffffff
28
- end
29
- if 1 < length
30
- h += (data[1] << 8) & 0xffffffff
31
- end
32
- if 0 < length
33
- h += data[0]
34
- h *= m
35
- h ^= h >> r
36
- end
37
-
38
- h *= m
39
- h ^= h >> 10
40
- h *= m
41
- h ^= h >> 17
42
-
43
- h
44
- end
13
+ over = Overflow.new "C" #=> "C" mean 8bit unsigned char (same as pack template)
14
+ over.set 255 #=> set a number (0b11111111)
15
+ p over.to_i #=> 255 (out Fixnum object)
16
+ over = over << 4 #=> left bit shift (0b11110000)
17
+ p over.to_i #=> 240 (overflow bit is dropped)
18
+ p (over >> 4).to_i #=> 15 (0b00001111)
19
+ p (200 - over) #=> -40 (Call Overflow#coerce.)
45
20
  ```
46
21
 
22
+ ## APIs
23
+
24
+ ### initialize(type[, number])
25
+
26
+ **type**: defined C type
27
+
28
+ All type mean same that pack template.
29
+
30
+ - c: `int8_t`
31
+ - C: `uint8_t`
32
+ - s: `int16_t`
33
+ - S: `uint16_t`
34
+ - i: `int`
35
+ - I: `unsigned int`
36
+ - l: `int32_t`
37
+ - L: `uint32_t`
38
+ - q: `int64_t`
39
+ - Q: `uint64_t`
40
+
41
+ ### set(number)
42
+
43
+ ```ruby
44
+ over = Overflow.new "C"
45
+ over.set 1
46
+ p over.to_i #=> 1
47
+ over.set 10
48
+ p over.to_i #=> 10
49
+ ```
50
+
51
+ ### to\_i
52
+
53
+ ```ruby
54
+ over = Overflow.new "C", 256
55
+ over.to_i #=> 0
56
+ ```
57
+
58
+ ### +, -, \*
59
+
60
+ ```ruby
61
+ over = Overflow.new "C", 100
62
+ over += 200 #=> 44
63
+ over -= 50 #=> 250
64
+ over *= 10 #=> 196
65
+ ```
66
+
67
+ ### ~, &, |, ^
68
+
69
+ ```ruby
70
+ over = Overflow.new "C", 0xaa
71
+ ~over #=> 0x55
72
+ over & 0x99 #=> 0x88
73
+ over | 0x99 #=> 0xbb
74
+ over ^ 0x99 #=> 0x33
75
+ ```
76
+
77
+ ### \<\<, \>\>
78
+
79
+ ```ruby
80
+ over = Overflow.new "C", 0xff
81
+ over << 4 #=> 0xf0
82
+ over >> 4 #=> 0x0f
83
+ ```
84
+
85
+ and all `Numeric` methods.
86
+
87
+ ## Class tree
88
+
89
+ Overflow < Numeric
90
+
47
91
  ## Installation
48
92
 
49
93
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -18,4 +18,4 @@ Rake::ExtensionTask.new('overflow', spec) do |ext|
18
18
  end
19
19
 
20
20
 
21
- task :default => [:spec]
21
+ task :default => [:spec, :build]
@@ -0,0 +1,44 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'overflow'
7
+
8
+ def murmur_hash str
9
+ data = str.dup.unpack("C*")
10
+ m = 0x5bd1e995
11
+ r = 16
12
+ length = Overflow.new "I", str.bytesize
13
+ h = length * m
14
+
15
+ while 4 <= length
16
+ d = data.shift(4).pack("C*").unpack("I")[0]
17
+ h += d
18
+ h *= m
19
+ h ^= h >> r
20
+ length -= 4
21
+ end
22
+
23
+ if 2 < length
24
+ h += data[2] << 16
25
+ end
26
+ if 1 < length
27
+ h += data[1] << 8
28
+ end
29
+ if 0 < length
30
+ h += data[0]
31
+ h *= m
32
+ h ^= h >> r
33
+ end
34
+
35
+ h *= m
36
+ h ^= h >> 10
37
+ h *= m
38
+ h ^= h >> 17
39
+
40
+ h.to_i
41
+ end
42
+
43
+ # p murmur_hash "murmur" #=> 2800467524
44
+ puts murmur_hash ARGV[0]
@@ -1,3 +1,5 @@
1
1
  require 'mkmf'
2
2
 
3
+ $CFLAGS << " -Wall"
4
+
3
5
  create_makefile('overflow/overflow')
@@ -0,0 +1,455 @@
1
+ #include "ruby.h"
2
+
3
+ #define OVERFLOW_TYPES_ALL_CASE(ptr, callback) do { \
4
+ switch (ptr->type) { \
5
+ case i8: ptr->value = (int8_t) callback; break; \
6
+ case ui8: ptr->value = (uint8_t) callback; break; \
7
+ case i16: ptr->value = (int16_t) callback; break; \
8
+ case ui16: ptr->value = (uint16_t) callback; break; \
9
+ case in: ptr->value = (int) callback; break; \
10
+ case uin: ptr->value = (unsigned int) callback; break; \
11
+ case i32: ptr->value = (int32_t) callback; break; \
12
+ case ui32: ptr->value = (uint32_t) callback; break; \
13
+ case i64: ptr->value = (int64_t) callback; break; \
14
+ case ui64: ptr->value = (uint64_t) callback; break; \
15
+ } \
16
+ } while(0)
17
+
18
+ #define TYPE_PLUS(type, value, other) ((type)((type)(value) + (type)(other)))
19
+ #define TYPE_MINUS(type, value, other) ((type)((type)(value) - (type)(other)))
20
+ #define TYPE_MUL(type, value, other) ((type)((type)(value) * (type)(other)))
21
+ #define TYPE_DIV(type, value, other) ((type)((type)(value) / (type)(other)))
22
+
23
+ #define SWITCH_MACRO(type, macro, a, b) do { \
24
+ switch (type) { \
25
+ case i8: a = macro(int8_t, a, b); break; \
26
+ case ui8: a = macro(uint8_t, a, b); break; \
27
+ case i16: a = macro(int16_t, a, b); break; \
28
+ case ui16: a = macro(uint16_t, a, b); break; \
29
+ case in: a = macro(int, a, b); break; \
30
+ case uin: a = macro(unsigned int, a, b); break; \
31
+ case i32: a = macro(int32_t, a, b); break; \
32
+ case ui32: a = macro(uint32_t, a, b); break; \
33
+ case i64: a = macro(int64_t, a, b); break; \
34
+ case ui64: a = macro(uint64_t, a, b); break; \
35
+ } \
36
+ } while(0)
37
+
38
+ typedef enum {
39
+ i8,
40
+ ui8,
41
+ i16,
42
+ ui16,
43
+ in,
44
+ uin,
45
+ i32,
46
+ ui32,
47
+ i64,
48
+ ui64
49
+ } types;
50
+
51
+ typedef struct {
52
+ types type;
53
+ uint64_t value;
54
+ } overflow_t;
55
+
56
+ static VALUE overflow_set(VALUE self, VALUE obj);
57
+
58
+ types char2type (char c)
59
+ {
60
+ switch (c) {
61
+ case 'c': return i8;
62
+ case 'C': return ui8;
63
+ case 's': return i16;
64
+ case 'S': return ui16;
65
+ case 'i': return in;
66
+ case 'I': return uin;
67
+ case 'l': return i32;
68
+ case 'L': return ui32;
69
+ case 'q': return i64;
70
+ case 'Q': return ui64;
71
+ default:
72
+ rb_raise(rb_eArgError, "type %c is not support", c);
73
+ }
74
+ }
75
+
76
+ static VALUE
77
+ overflow_alloc(VALUE self)
78
+ {
79
+ overflow_t* ptr = ALLOC(overflow_t);
80
+ return Data_Wrap_Struct(self, 0, -1, ptr);
81
+ }
82
+
83
+ static VALUE
84
+ overflow_initialize(int argc, VALUE *argv, VALUE self)
85
+ {
86
+ overflow_t *ptr;
87
+ char *p;
88
+ VALUE obj = argv[0];
89
+
90
+ if (argc < 1 || rb_type(obj) != T_STRING) {
91
+ rb_raise(rb_eArgError, "set a type char for `pack' template");
92
+ }
93
+
94
+ Data_Get_Struct(self, overflow_t, ptr);
95
+ p = RSTRING_PTR(obj);
96
+
97
+ ptr->type = char2type(*p);
98
+ ptr->value = 0;
99
+ if (1 < argc) {
100
+ overflow_set(self, argv[1]);
101
+ }
102
+ return self;
103
+ }
104
+
105
+ static VALUE
106
+ overflow_initialize_copy(VALUE copy, VALUE origin)
107
+ {
108
+ overflow_t *ptr_copy, *ptr_origin;
109
+
110
+ if (copy == origin) return copy;
111
+
112
+ rb_check_frozen(copy);
113
+
114
+ Data_Get_Struct(copy, overflow_t, ptr_copy);
115
+ Data_Get_Struct(origin, overflow_t, ptr_origin);
116
+
117
+ ptr_copy->value = ptr_origin->value;
118
+ ptr_copy->type = ptr_origin->type;
119
+
120
+ return copy;
121
+ }
122
+
123
+ static VALUE
124
+ overflow_to_i(VALUE self)
125
+ {
126
+ overflow_t *ptr;
127
+ Data_Get_Struct(self, overflow_t, ptr);
128
+
129
+ switch (ptr->type) {
130
+ case i8: return INT2NUM((int8_t)ptr->value);
131
+ case ui8: return UINT2NUM((uint8_t)ptr->value);
132
+ case i16: return INT2NUM((int16_t)ptr->value);
133
+ case ui16: return UINT2NUM((uint16_t)ptr->value);
134
+ case in: return LONG2NUM((int)ptr->value);
135
+ case uin: return ULONG2NUM((unsigned int)ptr->value);
136
+ case i32: return LONG2NUM((int32_t)ptr->value);
137
+ case ui32: return ULONG2NUM((uint32_t)ptr->value);
138
+ case i64: return LL2NUM((int64_t)ptr->value);
139
+ case ui64: return ULL2NUM((uint64_t)ptr->value);
140
+ }
141
+ rb_raise(rb_eRuntimeError, "undefined type seted");
142
+ return Qnil;
143
+ }
144
+
145
+ static VALUE
146
+ overflow_coerce(VALUE self, VALUE other)
147
+ {
148
+ if (CLASS_OF(self) == CLASS_OF(other)) {
149
+ return rb_assoc_new(overflow_to_i(other), overflow_to_i(self));
150
+ }
151
+ return rb_assoc_new(other, overflow_to_i(self));
152
+ }
153
+
154
+ static VALUE
155
+ overflow_cmp(VALUE self, VALUE other)
156
+ {
157
+ VALUE i;
158
+
159
+ if (self == other) return 0;
160
+
161
+ i = overflow_to_i(self);
162
+ if (i == other) return INT2FIX(0);
163
+
164
+ if (FIXNUM_P(i)) {
165
+ if (FIXNUM_P(other)) {
166
+ if (FIX2LONG(i) < FIX2LONG(other)) {
167
+ return INT2FIX(-1);
168
+ } else {
169
+ return INT2FIX(1);
170
+ }
171
+ } else if (RB_TYPE_P(other, T_BIGNUM)) {
172
+ return rb_big_cmp(rb_int2big(FIX2LONG(i)), other);
173
+ }
174
+ } else if (RB_TYPE_P(i, T_BIGNUM)) {
175
+ return rb_big_cmp(i, other);
176
+ }
177
+ return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
178
+ }
179
+
180
+ static VALUE
181
+ overflow_hash(VALUE self)
182
+ {
183
+ st_index_t h[2];
184
+ overflow_t *ptr;
185
+ Data_Get_Struct(self, overflow_t, ptr);
186
+ h[0] = NUM2LONG(rb_hash(INT2FIX(ptr->type)));
187
+ h[1] = NUM2LONG(rb_hash(overflow_to_i(self)));
188
+ return LONG2FIX(rb_memhash(h, sizeof(h)));
189
+ }
190
+
191
+ static VALUE
192
+ overflow_eql(VALUE self, VALUE other)
193
+ {
194
+ overflow_t *ptr_self;
195
+ overflow_t *ptr_other;
196
+
197
+ if (TYPE(other) != T_DATA) {
198
+ return Qfalse;
199
+ }
200
+ Data_Get_Struct(self, overflow_t, ptr_self);
201
+ Data_Get_Struct(other, overflow_t, ptr_other);
202
+ if (ptr_self->type != ptr_other->type) {
203
+ return Qfalse;
204
+ }
205
+ if (ptr_self->value != ptr_other->value) {
206
+ return Qfalse;
207
+ }
208
+ return Qtrue;
209
+ }
210
+
211
+ static VALUE
212
+ overflow_to_f(VALUE self)
213
+ {
214
+ return DBL2NUM((double)FIX2LONG(overflow_to_i(self)));
215
+ }
216
+
217
+ static VALUE
218
+ overflow_modulo(VALUE self, VALUE other)
219
+ {
220
+ return rb_funcall(overflow_to_i(self), '-', 1,
221
+ rb_funcall(other, '*', 1,
222
+ rb_funcall(overflow_to_i(self), rb_intern("div"), 1, other)));
223
+ }
224
+
225
+ static VALUE
226
+ overflow_int_p(VALUE self)
227
+ {
228
+ return Qtrue;
229
+ }
230
+
231
+ static VALUE
232
+ overflow_set(VALUE self, VALUE obj)
233
+ {
234
+ VALUE other;
235
+ overflow_t *ptr;
236
+ Data_Get_Struct(self, overflow_t, ptr);
237
+
238
+ switch (rb_type(obj)) {
239
+ case T_FIXNUM:
240
+ OVERFLOW_TYPES_ALL_CASE(ptr, NUM2LL(obj));
241
+ break;
242
+ case T_BIGNUM:
243
+ if (RBIGNUM_POSITIVE_P(obj)) {
244
+ other = rb_funcall(obj, rb_intern("&"), 1, ULL2NUM(0xffffffffffffffffLL));
245
+ ptr->value = (uint64_t) NUM2ULL(other);
246
+ } else {
247
+ ptr->value = (int64_t) NUM2LL(obj);
248
+ }
249
+ break;
250
+ }
251
+ return self;
252
+ }
253
+
254
+ static inline VALUE
255
+ pre_arithmetic(VALUE num)
256
+ {
257
+ switch (rb_type(num)) {
258
+ case T_FIXNUM:
259
+ return num;
260
+ case T_BIGNUM:
261
+ return rb_funcall(num, rb_intern("&"), 1, ULL2NUM(0xffffffffffffffffLL));
262
+ case T_DATA: // self
263
+ return overflow_to_i(num);
264
+ }
265
+ rb_raise(rb_eArgError, "cannot arithmetic");
266
+ return Qnil;
267
+ }
268
+
269
+ static inline VALUE
270
+ overflow_arithmetic(VALUE self, char method, VALUE other)
271
+ {
272
+ uint64_t b;
273
+ overflow_t *ptr;
274
+ VALUE clone = rb_obj_clone(self);
275
+
276
+ Data_Get_Struct(clone, overflow_t, ptr);
277
+
278
+ b = NUM2ULL(pre_arithmetic(other));
279
+
280
+ switch (method) {
281
+ case '+':
282
+ SWITCH_MACRO(ptr->type, TYPE_PLUS, ptr->value, b);
283
+ break;
284
+ case '-':
285
+ SWITCH_MACRO(ptr->type, TYPE_MINUS, ptr->value, b);
286
+ break;
287
+ case '*':
288
+ SWITCH_MACRO(ptr->type, TYPE_MUL, ptr->value, b);
289
+ break;
290
+ case '/':
291
+ SWITCH_MACRO(ptr->type, TYPE_DIV, ptr->value, b);
292
+ break;
293
+ }
294
+ return clone;
295
+ }
296
+
297
+ static VALUE
298
+ overflow_plus(VALUE self, VALUE num)
299
+ {
300
+ return overflow_arithmetic(self, '+', num);
301
+ }
302
+
303
+ static VALUE
304
+ overflow_minus(VALUE self, VALUE num)
305
+ {
306
+ return overflow_arithmetic(self, '-', num);
307
+ }
308
+
309
+ static VALUE
310
+ overflow_mul(VALUE self, VALUE num)
311
+ {
312
+ return overflow_arithmetic(self, '*', num);
313
+ }
314
+
315
+ static VALUE
316
+ overflow_div(VALUE self, VALUE num)
317
+ {
318
+ return overflow_arithmetic(self, '/', num);
319
+ }
320
+
321
+ static VALUE
322
+ overflow_rev(VALUE self)
323
+ {
324
+ VALUE clone = rb_obj_clone(self);
325
+ overflow_t *ptr;
326
+ Data_Get_Struct(clone, overflow_t, ptr);
327
+
328
+ ptr->value = ~ptr->value;
329
+ return clone;
330
+ }
331
+
332
+ static VALUE
333
+ overflow_and(VALUE self, VALUE num)
334
+ {
335
+ VALUE clone = rb_obj_clone(self);
336
+ overflow_t *ptr;
337
+ Data_Get_Struct(clone, overflow_t, ptr);
338
+
339
+ ptr->value = ptr->value & NUM2ULL(pre_arithmetic(num));
340
+ return clone;
341
+ }
342
+
343
+ static VALUE
344
+ overflow_or(VALUE self, VALUE num)
345
+ {
346
+ VALUE clone = rb_obj_clone(self);
347
+ overflow_t *ptr;
348
+ Data_Get_Struct(clone, overflow_t, ptr);
349
+
350
+ ptr->value = ptr->value | NUM2ULL(pre_arithmetic(num));
351
+ return clone;
352
+ }
353
+
354
+ static VALUE
355
+ overflow_xor(VALUE self, VALUE num)
356
+ {
357
+ VALUE clone = rb_obj_clone(self);
358
+ overflow_t *ptr;
359
+ Data_Get_Struct(clone, overflow_t, ptr);
360
+
361
+ ptr->value = ptr->value ^ NUM2ULL(pre_arithmetic(num));
362
+ return clone;
363
+ }
364
+
365
+ static void
366
+ lshift(overflow_t *ptr, long width)
367
+ {
368
+ OVERFLOW_TYPES_ALL_CASE(ptr, (ptr->value << width));
369
+ }
370
+
371
+ static void
372
+ rshift(overflow_t *ptr, long width)
373
+ {
374
+ OVERFLOW_TYPES_ALL_CASE(ptr, (ptr->value >> width));
375
+ }
376
+
377
+ static VALUE
378
+ overflow_lshift(VALUE self, VALUE obj)
379
+ {
380
+ VALUE clone = rb_obj_clone(self);
381
+ long width;
382
+ overflow_t *ptr;
383
+ Data_Get_Struct(clone, overflow_t, ptr);
384
+
385
+ if (!FIXNUM_P(obj))
386
+ rb_raise(rb_eArgError, "too big shift not support");
387
+
388
+ width = FIX2LONG(obj);
389
+
390
+ if (width < 0) {
391
+ rshift(ptr, -width);
392
+ } else {
393
+ lshift(ptr, width);
394
+ }
395
+ return clone;
396
+ }
397
+
398
+ static VALUE
399
+ overflow_rshift(VALUE self, VALUE obj)
400
+ {
401
+ VALUE clone = rb_obj_clone(self);
402
+ long width;
403
+ overflow_t *ptr;
404
+ Data_Get_Struct(clone, overflow_t, ptr);
405
+
406
+ if (!FIXNUM_P(obj))
407
+ rb_raise(rb_eArgError, "too big shift not support");
408
+
409
+ width = FIX2LONG(obj);
410
+
411
+ if (width < 0) {
412
+ lshift(ptr, -width);
413
+ } else {
414
+ rshift(ptr, width);
415
+ }
416
+ return clone;
417
+ }
418
+
419
+ void
420
+ Init_overflow(void)
421
+ {
422
+ VALUE cOverflow;
423
+
424
+ cOverflow = rb_define_class("Overflow", rb_cNumeric);
425
+ rb_define_const(cOverflow, "VERSION", rb_str_new2("0.0.1"));
426
+ rb_define_alloc_func(cOverflow, overflow_alloc);
427
+ rb_define_method(cOverflow, "initialize", overflow_initialize, -1);
428
+ rb_define_method(cOverflow, "initialize_copy", overflow_initialize_copy, 1);
429
+
430
+ /* override on Numeric */
431
+ rb_define_method(cOverflow, "coerce", overflow_coerce, 1);
432
+ rb_define_method(cOverflow, "<=>", overflow_cmp, 1);
433
+ rb_define_method(cOverflow, "hash", overflow_hash, 0);
434
+ rb_define_method(cOverflow, "eql?", overflow_eql, 1);
435
+ rb_define_method(cOverflow, "to_f", overflow_to_f, 0);
436
+ rb_define_method(cOverflow, "%", overflow_modulo, 1);
437
+ rb_define_method(cOverflow, "modulo", overflow_modulo, 1);
438
+ rb_define_method(cOverflow, "integer?", overflow_int_p, 0);
439
+
440
+ rb_define_method(cOverflow, "set", overflow_set, 1);
441
+ rb_define_method(cOverflow, "to_i", overflow_to_i, 0);
442
+
443
+ rb_define_method(cOverflow, "+", overflow_plus, 1);
444
+ rb_define_method(cOverflow, "-", overflow_minus, 1);
445
+ rb_define_method(cOverflow, "*", overflow_mul, 1);
446
+ rb_define_method(cOverflow, "/", overflow_div, 1);
447
+
448
+ rb_define_method(cOverflow, "~", overflow_rev, 0);
449
+ rb_define_method(cOverflow, "&", overflow_and, 1);
450
+ rb_define_method(cOverflow, "|", overflow_or, 1);
451
+ rb_define_method(cOverflow, "^", overflow_xor, 1);
452
+
453
+ rb_define_method(cOverflow, "<<", overflow_lshift, 1);
454
+ rb_define_method(cOverflow, ">>", overflow_rshift, 1);
455
+ }