222
222
return rb_int2big(n);
225
#ifdef HAVE_LONG_LONG
225
#if SIZEOF_LONG % SIZEOF_BDIGITS != 0
226
# error unexpected SIZEOF_LONG : SIZEOF_BDIGITS ratio
230
* buf is an array of long integers.
231
* buf is ordered from least significant word to most significant word.
232
* buf[0] is the least significant word and
233
* buf[num_longs-1] is the most significant word.
234
* This means words in buf is little endian.
235
* However each word in buf is native endian.
236
* (buf[i]&1) is the least significant bit and
237
* (buf[i]&(1<<(SIZEOF_LONG*CHAR_BIT-1))) is the most significant bit
238
* for each 0 <= i < num_longs.
239
* So buf is little endian at whole on a little endian machine.
240
* But buf is mixed endian on a big endian machine.
243
rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
245
val = rb_to_int(val);
250
long tmp = FIX2LONG(val);
251
buf[0] = (unsigned long)tmp;
252
tmp = tmp < 0 ? ~0L : 0;
253
for (i = 1; i < num_longs; i++)
254
buf[i] = (unsigned long)tmp;
258
long len = RBIGNUM_LEN(val);
259
BDIGIT *ds = BDIGITS(val), *dend = ds + len;
261
for (i = 0; i < num_longs && ds < dend; i++) {
263
for (j = 0; j < DIGSPERLONG && ds < dend; j++, ds++) {
264
l |= ((unsigned long)*ds << (j * BITSPERDIG));
268
for (; i < num_longs; i++)
270
if (RBIGNUM_NEGATIVE_P(val)) {
271
for (i = 0; i < num_longs; i++) {
274
for (i = 0; i < num_longs; i++) {
283
/* See rb_big_pack comment for endianness of buf. */
285
rb_big_unpack(unsigned long *buf, long num_longs)
287
while (2 <= num_longs) {
288
if (buf[num_longs-1] == 0 && (long)buf[num_longs-2] >= 0)
290
else if (buf[num_longs-1] == ~0UL && (long)buf[num_longs-2] < 0)
297
else if (num_longs == 1)
298
return LONG2NUM((long)buf[0]);
302
long len = num_longs * DIGSPERLONG;
304
big = bignew(len, 1);
306
for (i = 0; i < num_longs; i++) {
307
unsigned long d = buf[i];
308
#if SIZEOF_LONG == SIZEOF_BDIGITS
312
for (j = 0; j < DIGSPERLONG; j++) {
318
if ((long)buf[num_longs-1] < 0) {
320
RBIGNUM_SET_SIGN(big, 0);
328
#if SIZEOF_LONG_LONG == QUAD_SIZE && SIZEOF_BDIGITS*2 == SIZEOF_LONG_LONG
228
331
rb_quad_pack(buf, val)
314
429
rb_raise(rb_eRangeError, "bignum too big to convert into `quad int'");
316
431
memcpy(buf, (char*)BDIGITS(val), len);
317
if (!RBIGNUM(val)->sign) {
432
if (RBIGNUM_NEGATIVE_P(val)) {
433
quad_buf_complement(buf, QUAD_SIZE);