Class: Overflow

Inherits:
Numeric
  • Object
show all
Defined in:
ext/overflow/overflow.c

Constant Summary collapse

VERSION =
rb_str_new2("0.0.1")

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'ext/overflow/overflow.c', line 83

static VALUE
overflow_initialize(int argc, VALUE *argv, VALUE self)
{
	overflow_t *ptr;
	char *p;
	VALUE obj = argv[0];

	if (argc < 1 || rb_type(obj) != T_STRING) {
		rb_raise(rb_eArgError, "set a type char for `pack' template");
	}

	Data_Get_Struct(self, overflow_t, ptr);
	p = RSTRING_PTR(obj);

	ptr->type = char2type(*p);
	ptr->value = 0;
	if (1 < argc) {
		overflow_set(self, argv[1]);
	}
	return self;
}

Instance Method Details

#%(other) ⇒ Object



217
218
219
220
221
222
223
# File 'ext/overflow/overflow.c', line 217

static VALUE
overflow_modulo(VALUE self, VALUE other)
{
	return rb_funcall(overflow_to_i(self), '-', 1,
			rb_funcall(other, '*', 1,
				rb_funcall(overflow_to_i(self), rb_intern("div"), 1, other)));
}

#&(num) ⇒ Object



332
333
334
335
336
337
338
339
340
341
# File 'ext/overflow/overflow.c', line 332

static VALUE
overflow_and(VALUE self, VALUE num)
{
	VALUE clone = rb_obj_clone(self);
	overflow_t *ptr;
	Data_Get_Struct(clone, overflow_t, ptr);

	ptr->value = ptr->value & NUM2ULL(pre_arithmetic(num));
	return clone;
}

#*(num) ⇒ Object



309
310
311
312
313
# File 'ext/overflow/overflow.c', line 309

static VALUE
overflow_mul(VALUE self, VALUE num)
{
	return overflow_arithmetic(self, '*', num);
}

#+(num) ⇒ Object



297
298
299
300
301
# File 'ext/overflow/overflow.c', line 297

static VALUE
overflow_plus(VALUE self, VALUE num)
{
	return overflow_arithmetic(self, '+', num);
}

#-(num) ⇒ Object



303
304
305
306
307
# File 'ext/overflow/overflow.c', line 303

static VALUE
overflow_minus(VALUE self, VALUE num)
{
	return overflow_arithmetic(self, '-', num);
}

#/(num) ⇒ Object



315
316
317
318
319
# File 'ext/overflow/overflow.c', line 315

static VALUE
overflow_div(VALUE self, VALUE num)
{
	return overflow_arithmetic(self, '/', num);
}

#<<(obj) ⇒ Object



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'ext/overflow/overflow.c', line 377

static VALUE
overflow_lshift(VALUE self, VALUE obj)
{
	VALUE clone = rb_obj_clone(self);
	long width;
	overflow_t *ptr;
	Data_Get_Struct(clone, overflow_t, ptr);

	if (!FIXNUM_P(obj))
		rb_raise(rb_eArgError, "too big shift not support");

	width = FIX2LONG(obj);

	if (width < 0) {
		rshift(ptr, -width);
	} else {
		lshift(ptr, width);
	}
	return clone;
}

#<=>(other) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'ext/overflow/overflow.c', line 154

static VALUE
overflow_cmp(VALUE self, VALUE other)
{
	VALUE i;

	if (self == other) return 0;

	i = overflow_to_i(self);
	if (i == other) return INT2FIX(0);

	if (FIXNUM_P(i)) {
		if (FIXNUM_P(other)) {
			if (FIX2LONG(i) < FIX2LONG(other)) {
				return INT2FIX(-1);
			} else {
				return INT2FIX(1);
			}
		} else if (RB_TYPE_P(other, T_BIGNUM)) {
			return rb_big_cmp(rb_int2big(FIX2LONG(i)), other);
		}
	} else if (RB_TYPE_P(i, T_BIGNUM)) {
		return rb_big_cmp(i, other);
	}
	return rb_num_coerce_cmp(self, other, rb_intern("<=>"));
}

#>>(obj) ⇒ Object



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'ext/overflow/overflow.c', line 398

static VALUE
overflow_rshift(VALUE self, VALUE obj)
{
	VALUE clone = rb_obj_clone(self);
	long width;
	overflow_t *ptr;
	Data_Get_Struct(clone, overflow_t, ptr);

	if (!FIXNUM_P(obj))
		rb_raise(rb_eArgError, "too big shift not support");

	width = FIX2LONG(obj);

	if (width < 0) {
		lshift(ptr, -width);
	} else {
		rshift(ptr, width);
	}
	return clone;
}

#^(num) ⇒ Object



354
355
356
357
358
359
360
361
362
363
# File 'ext/overflow/overflow.c', line 354

static VALUE
overflow_xor(VALUE self, VALUE num)
{
	VALUE clone = rb_obj_clone(self);
	overflow_t *ptr;
	Data_Get_Struct(clone, overflow_t, ptr);

	ptr->value = ptr->value ^ NUM2ULL(pre_arithmetic(num));
	return clone;
}

#coerce(other) ⇒ Object

override on Numeric



145
146
147
148
149
150
151
152
# File 'ext/overflow/overflow.c', line 145

static VALUE
overflow_coerce(VALUE self, VALUE other)
{
	if (CLASS_OF(self) == CLASS_OF(other)) {
		return rb_assoc_new(overflow_to_i(other), overflow_to_i(self));
	}
	return rb_assoc_new(other, overflow_to_i(self));
}

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'ext/overflow/overflow.c', line 191

static VALUE
overflow_eql(VALUE self, VALUE other)
{
	overflow_t *ptr_self;
	overflow_t *ptr_other;

	if (TYPE(other) != T_DATA) {
		return Qfalse;
	}
	Data_Get_Struct(self, overflow_t, ptr_self);
	Data_Get_Struct(other, overflow_t, ptr_other);
	if (ptr_self->type != ptr_other->type) {
		return Qfalse;
	}
	if (ptr_self->value != ptr_other->value) {
		return Qfalse;
	}
	return Qtrue;
}

#hashObject



180
181
182
183
184
185
186
187
188
189
# File 'ext/overflow/overflow.c', line 180

static VALUE
overflow_hash(VALUE self)
{
	st_index_t h[2];
	overflow_t *ptr;
	Data_Get_Struct(self, overflow_t, ptr);
	h[0] = NUM2LONG(rb_hash(INT2FIX(ptr->type)));
	h[1] = NUM2LONG(rb_hash(overflow_to_i(self)));
	return LONG2FIX(rb_memhash(h, sizeof(h)));
}

#initialize_copy(origin) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'ext/overflow/overflow.c', line 105

static VALUE
overflow_initialize_copy(VALUE copy, VALUE origin)
{
	overflow_t *ptr_copy, *ptr_origin;

	if (copy == origin) return copy;

	rb_check_frozen(copy);

	Data_Get_Struct(copy, overflow_t, ptr_copy);
	Data_Get_Struct(origin, overflow_t, ptr_origin);

	ptr_copy->value = ptr_origin->value;
	ptr_copy->type  = ptr_origin->type;

	return copy;
}

#integer?Boolean

Returns:

  • (Boolean)


225
226
227
228
229
# File 'ext/overflow/overflow.c', line 225

static VALUE
overflow_int_p(VALUE self)
{
	return Qtrue;
}

#modulo(other) ⇒ Object



217
218
219
220
221
222
223
# File 'ext/overflow/overflow.c', line 217

static VALUE
overflow_modulo(VALUE self, VALUE other)
{
	return rb_funcall(overflow_to_i(self), '-', 1,
			rb_funcall(other, '*', 1,
				rb_funcall(overflow_to_i(self), rb_intern("div"), 1, other)));
}

#set(obj) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'ext/overflow/overflow.c', line 231

static VALUE
overflow_set(VALUE self, VALUE obj)
{
	VALUE other;
	overflow_t *ptr;
	Data_Get_Struct(self, overflow_t, ptr);

	switch (rb_type(obj)) {
	case T_FIXNUM:
		OVERFLOW_TYPES_ALL_CASE(ptr, NUM2LL(obj));
		break;
	case T_BIGNUM:
		if (RBIGNUM_POSITIVE_P(obj)) {
			other = rb_funcall(obj, rb_intern("&"), 1, ULL2NUM(0xffffffffffffffffLL));
			ptr->value = (uint64_t) NUM2ULL(other);
		} else {
			ptr->value = (int64_t) NUM2LL(obj);
		}
		break;
	}
	return self;
}

#to_fObject



211
212
213
214
215
# File 'ext/overflow/overflow.c', line 211

static VALUE
overflow_to_f(VALUE self)
{
	return DBL2NUM((double)FIX2LONG(overflow_to_i(self)));
}

#to_iObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'ext/overflow/overflow.c', line 123

static VALUE
overflow_to_i(VALUE self)
{
	overflow_t *ptr;
	Data_Get_Struct(self, overflow_t, ptr);

	switch (ptr->type) {
	case i8:   return INT2NUM((int8_t)ptr->value);
	case ui8:  return UINT2NUM((uint8_t)ptr->value);
	case i16:  return INT2NUM((int16_t)ptr->value);
	case ui16: return UINT2NUM((uint16_t)ptr->value);
	case in:   return LONG2NUM((int)ptr->value);
	case uin:  return ULONG2NUM((unsigned int)ptr->value);
	case i32:  return LONG2NUM((int32_t)ptr->value);
	case ui32: return ULONG2NUM((uint32_t)ptr->value);
	case i64:  return LL2NUM((int64_t)ptr->value);
	case ui64: return ULL2NUM((uint64_t)ptr->value);
	}
	rb_raise(rb_eRuntimeError, "undefined type seted");
	return Qnil;
}

#|(num) ⇒ Object



343
344
345
346
347
348
349
350
351
352
# File 'ext/overflow/overflow.c', line 343

static VALUE
overflow_or(VALUE self, VALUE num)
{
	VALUE clone = rb_obj_clone(self);
	overflow_t *ptr;
	Data_Get_Struct(clone, overflow_t, ptr);

	ptr->value = ptr->value | NUM2ULL(pre_arithmetic(num));
	return clone;
}

#~Object



321
322
323
324
325
326
327
328
329
330
# File 'ext/overflow/overflow.c', line 321

static VALUE
overflow_rev(VALUE self)
{
	VALUE clone = rb_obj_clone(self);
	overflow_t *ptr;
	Data_Get_Struct(clone, overflow_t, ptr);

	ptr->value = ~ptr->value;
	return clone;
}