/* * call-seq: * fix.divmod(numeric) -> array * * See <code>Numeric#divmod</code>. */ static mrb_value fix_divmod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_get_args(mrb, "o", &y); if (mrb_fixnum_p(y)) { mrb_int div, mod; if (mrb_fixnum(y) == 0) { return mrb_assoc_new(mrb, mrb_float_value(str_to_mrb_float("inf")), mrb_float_value(str_to_mrb_float("nan"))); } fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); } else { mrb_float div, mod; mrb_value a, b; flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod); a = mrb_float_value((mrb_int)div); b = mrb_float_value(mod); return mrb_assoc_new(mrb, a, b); } }
static void flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp) { mrb_float div; mrb_float mod; if (y == 0.0) { div = str_to_mrb_float("inf"); mod = str_to_mrb_float("nan"); } else { mod = fmod(x, y); if (isinf(x) && !isinf(y) && !isnan(y)) div = x; else div = (x - mod) / y; if (y*mod < 0) { mod += y; div -= 1.0; } } if (modp) *modp = mod; if (divp) *divp = div; }
static mrb_value fix_mod(mrb_state *mrb, mrb_value x) { mrb_value y; mrb_int a, b; mrb_get_args(mrb, "o", &y); a = mrb_fixnum(x); if (mrb_fixnum_p(y) && (b=mrb_fixnum(y)) != 0) { mrb_int mod; if (mrb_fixnum(y) == 0) { return mrb_float_value(str_to_mrb_float("nan")); } fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod); return mrb_fixnum_value(mod); } else { mrb_float mod; flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mod); } }
static int read_rite_irep_record(mrb_state *mrb, unsigned char *src, uint32_t* len) { int i, ret = MRB_DUMP_OK; char *buf; unsigned char *recordStart, *pStart; uint16_t crc, tt, pdl, snl, offset, bufsize=MRB_DUMP_DEFAULT_STR_LEN; mrb_int fix_num; mrb_float f; int plen; int ai = mrb_gc_arena_save(mrb); mrb_irep *irep = mrb_add_irep(mrb); recordStart = src; buf = (char *)mrb_malloc(mrb, bufsize); if (buf == NULL) { ret = MRB_DUMP_INVALID_IREP; goto error_exit; } //Header Section pStart = src; if (*src != RITE_IREP_IDENFIFIER) return MRB_DUMP_INVALID_IREP; src += (sizeof(unsigned char) * 2); irep->nlocals = bin_to_uint16(src); //number of local variable src += MRB_DUMP_SIZE_OF_SHORT; irep->nregs = bin_to_uint16(src); //number of register variable src += MRB_DUMP_SIZE_OF_SHORT; offset = bin_to_uint16(src); //offset of isec block src += MRB_DUMP_SIZE_OF_SHORT; crc = calc_crc_16_ccitt(pStart, src - pStart); //Calculate CRC if (crc != bin_to_uint16(src)) //header CRC return MRB_DUMP_INVALID_IREP; src += offset; //Binary Data Section //ISEQ BLOCK pStart = src; irep->ilen = bin_to_uint32(src); //iseq length src += MRB_DUMP_SIZE_OF_LONG; if (irep->ilen > 0) { if ((irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen)) == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } for (i=0; i<irep->ilen; i++) { irep->iseq[i] = bin_to_uint32(src); //iseq src += MRB_DUMP_SIZE_OF_LONG; } } crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC if (crc != bin_to_uint16(src)) { //iseq CRC ret = MRB_DUMP_INVALID_IREP; goto error_exit; } src += MRB_DUMP_SIZE_OF_SHORT; //POOL BLOCK pStart = src; plen = bin_to_uint32(src); //pool length src += MRB_DUMP_SIZE_OF_LONG; if (plen > 0) { irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * plen); if (irep->pool == NULL) { ret = MRB_DUMP_INVALID_IREP; goto error_exit; } for (i=0; i<plen; i++) { tt = *src; //pool TT src += sizeof(unsigned char); pdl = bin_to_uint16(src); //pool data length src += MRB_DUMP_SIZE_OF_SHORT; if (pdl > bufsize - 1) { mrb_free(mrb, buf); bufsize = pdl + 1; if ((buf = (char *)mrb_malloc(mrb, bufsize)) == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } } memcpy(buf, src, pdl); src += pdl; buf[pdl] = '\0'; switch (tt) { //pool data case MRB_TT_FIXNUM: fix_num = str_to_mrb_int(buf); irep->pool[i] = mrb_fixnum_value(fix_num); break; case MRB_TT_FLOAT: f = str_to_mrb_float(buf); irep->pool[i] = mrb_float_value(f); break; case MRB_TT_STRING: irep->pool[i] = mrb_str_new(mrb, buf, pdl); break; #ifdef ENABLE_REGEXP case MRB_TT_REGEX: str = mrb_str_new(mrb, buf, pdl); irep->pool[i] = mrb_reg_quote(mrb, str); break; #endif default: irep->pool[i] = mrb_nil_value(); break; } irep->plen++; mrb_gc_arena_restore(mrb, ai); } } crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC if (crc != bin_to_uint16(src)) { //pool CRC ret = MRB_DUMP_INVALID_IREP; goto error_exit; } src += MRB_DUMP_SIZE_OF_SHORT; //SYMS BLOCK pStart = src; irep->slen = bin_to_uint32(src); //syms length src += MRB_DUMP_SIZE_OF_LONG; if (irep->slen > 0) { if ((irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen)) == NULL) { ret = MRB_DUMP_INVALID_IREP; goto error_exit; } for (i = 0; i < irep->slen; i++) { static const mrb_sym mrb_sym_zero = { 0 }; *irep->syms = mrb_sym_zero; } for (i=0; i<irep->slen; i++) { snl = bin_to_uint16(src); //symbol name length src += MRB_DUMP_SIZE_OF_SHORT; if (snl == MRB_DUMP_NULL_SYM_LEN) { irep->syms[i] = 0; continue; } if (snl > bufsize - 1) { mrb_free(mrb, buf); bufsize = snl + 1; if ((buf = (char *)mrb_malloc(mrb, bufsize)) == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } } memcpy(buf, src, snl); //symbol name src += snl; buf[snl] = '\0'; irep->syms[i] = mrb_intern2(mrb, buf, snl); } } crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC if (crc != bin_to_uint16(src)) { //syms CRC ret = MRB_DUMP_INVALID_IREP; goto error_exit; } src += MRB_DUMP_SIZE_OF_SHORT; *len = src - recordStart; error_exit: if (buf) mrb_free(mrb, buf); return ret; }