Z3_bool Z3_API Z3_get_numeral_small(Z3_context c, Z3_ast a, int64_t* num, int64_t* den) { Z3_TRY; // This function invokes Z3_get_numeral_rational, but it is still ok to add LOG command here because it does not return a Z3 object. LOG_Z3_get_numeral_small(c, a, num, den); RESET_ERROR_CODE(); CHECK_IS_EXPR(a, Z3_FALSE); rational r; Z3_bool ok = Z3_get_numeral_rational(c, a, r); if (ok == Z3_TRUE) { rational n = numerator(r); rational d = denominator(r); if (n.is_int64() && d.is_int64()) { *num = n.get_int64(); *den = d.get_int64(); return Z3_TRUE; } else { return Z3_FALSE; } } SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); return Z3_FALSE; Z3_CATCH_RETURN(Z3_FALSE); }
sample_rate sample_rate::common( const sample_rate &o ) const { auto x = _ratio.common( o._ratio ); return sample_rate( x.numerator(), x.denominator() ); }
void manualFRTest() { TFile* f = TFile::Open("/eos/user/v/vischia/www/taufakes_new/plotter_wjet.root", "READ"); TString data("data (single mu)"), ttbar("TTbar"), wjets("W#rightarrow l#nu inclusive"), qcd("QCD_EMEnr_Incl"); TString numerator("/wjet_step5byLooseCombinedIsolationDeltaBetaCorr3Hitseta_numerator"), denominator("/wjet_step5eta_denominator"); TH1F* data_num = (TH1F*) f->Get(data+numerator); TH1F* data_den = (TH1F*) f->Get(data+denominator); TH1F* ttbar_num = (TH1F*) f->Get(ttbar+numerator); TH1F* ttbar_den = (TH1F*) f->Get(ttbar+denominator); TH1F* wjets_num = (TH1F*) f->Get(wjets+numerator); TH1F* wjets_den = (TH1F*) f->Get(wjets+denominator); TH1F* qcd_num = (TH1F*) f->Get(qcd+numerator); TH1F* qcd_den = (TH1F*) f->Get(qcd+denominator); TH1F* mc_num = (TH1F*) ttbar_num->Clone("mc_num"); mc_num->Add(wjets_num); //mc_num->Add(qcd_num); TH1F* mc_den = (TH1F*) ttbar_den->Clone("mc_den"); mc_den->Add(wjets_den); //mc_den->Add(qcd_den); data_num->SetMarkerColor(kBlack); mc_num->SetMarkerColor(kRed); data_den->SetMarkerColor(kBlack); mc_den->SetMarkerColor(kRed); TCanvas* d = new TCanvas("d", "d", 600, 1200); d->Divide(1,2); d->cd(1); gPad->SetTitle("numerator"); data_num->DrawCopy("pe"); mc_num->DrawCopy("pesame"); d->cd(2); gPad->SetTitle("denominator"); data_den->DrawCopy("pe"); mc_den->DrawCopy("pesame"); TH1F* data_fr = (TH1F*) data_num->Clone("data_fr"); data_fr->Divide(data_den); TH1F* mc_fr = (TH1F*) mc_num->Clone("mc_fr"); mc_fr->Divide(mc_den); data_fr->SetMarkerColor(kBlack); mc_fr->SetMarkerColor(kRed); data_fr->SetMarkerSize(2); mc_fr->SetMarkerSize(2); TCanvas* c = new TCanvas("c", "c", 600, 600); c->cd(); data_fr->Draw("pe"); mc_fr->Draw("pesame"); }
void goto_convertt::do_prob_coin( const exprt &lhs, const exprt &function, const exprt::operandst &arguments, goto_programt &dest) { const irep_idt &identifier=function.get(ID_identifier); // make it a side effect if there is an LHS if(arguments.size()!=2) { err_location(function); throw "`"+id2string(identifier)+"' expected to have two arguments"; } if(lhs.is_nil()) { err_location(function); throw "`"+id2string(identifier)+"' expected to have LHS"; } exprt rhs=side_effect_exprt("prob_coin", lhs.type()); rhs.add_source_location()=function.source_location(); if(lhs.type()!=bool_typet()) { err_location(function); throw "`"+id2string(identifier)+"' expected bool"; } if(arguments[0].type().id()!=ID_unsignedbv || arguments[0].id()!=ID_constant) { err_location(function); throw "`"+id2string(identifier)+"' expected first " "operand to be a constant literal of type unsigned long"; } mp_integer num, den; if(to_integer(arguments[0], num) || to_integer(arguments[1], den)) { err_location(function); throw "error converting operands"; } if(num-den > mp_integer(0)) { err_location(function); throw "probability has to be smaller than 1"; } if(den == mp_integer(0)) { err_location(function); throw "denominator may not be zero"; } rationalt numerator(num), denominator(den); rationalt prob = numerator / denominator; rhs.copy_to_operands(from_rational(prob)); code_assignt assignment(lhs, rhs); assignment.add_source_location()=function.source_location(); copy(assignment, ASSIGN, dest); }
void expand(void) { save(); X = pop(); F = pop(); if (istensor(F)) { expand_tensor(); restore(); return; } // if sum of terms then sum over the expansion of each term if (car(F) == symbol(ADD)) { push_integer(0); p1 = cdr(F); while (iscons(p1)) { push(car(p1)); push(X); expand(); add(); p1 = cdr(p1); } restore(); return; } // B = numerator push(F); numerator(); B = pop(); // A = denominator push(F); denominator(); A = pop(); remove_negative_exponents(); // Q = quotient push(B); push(A); push(X); divpoly(); Q = pop(); // remainder B = B - A * Q push(B); push(A); push(Q); multiply(); subtract(); B = pop(); // if the remainder is zero then we're done if (iszero(B)) { push(Q); restore(); return; } // A = factor(A) push(A); push(X); factorpoly(); A = pop(); expand_get_C(); expand_get_B(); expand_get_A(); if (istensor(C)) { push(C); inv(); push(B); inner(); push(A); inner(); } else { push(B); push(C); divide(); push(A); multiply(); } push(Q); add(); restore(); }
long double to_long_double() { return static_cast<long double>(numerator()) / denominator(); }
float cost_evaluator::eval(expr * f) const { #define E(IDX) eval(to_app(f)->get_arg(IDX)) if (is_app(f)) { unsigned num_args; family_id fid = to_app(f)->get_family_id(); if (fid == m_manager.get_basic_family_id()) { switch (to_app(f)->get_decl_kind()) { case OP_TRUE: return 1.0f; case OP_FALSE: return 0.0f; case OP_NOT: return E(0) == 0.0f ? 1.0f : 0.0f; case OP_AND: num_args = to_app(f)->get_num_args(); for (unsigned i = 0; i < num_args; i++) if (E(i) == 0.0f) return 0.0f; return 1.0f; case OP_OR: num_args = to_app(f)->get_num_args(); for (unsigned i = 0; i < num_args; i++) if (E(i) != 0.0f) return 1.0f; return 0.0f; case OP_ITE: return E(0) != 0.0f ? E(1) : E(2); case OP_EQ: case OP_IFF: return E(0) == E(1) ? 1.0f : 0.0f; case OP_XOR: return E(0) != E(1) ? 1.0f : 0.0f; case OP_IMPLIES: if (E(0) == 0.0f) return 1.0f; return E(1) != 0.0f ? 1.0f : 0.0f; default: ; } } else if (fid == m_util.get_family_id()) { switch (to_app(f)->get_decl_kind()) { case OP_NUM: { rational r = to_app(f)->get_decl()->get_parameter(0).get_rational(); return static_cast<float>(numerator(r).get_int64())/static_cast<float>(denominator(r).get_int64()); } case OP_LE: return E(0) <= E(1) ? 1.0f : 0.0f; case OP_GE: return E(0) >= E(1) ? 1.0f : 0.0f; case OP_LT: return E(0) < E(1) ? 1.0f : 0.0f; case OP_GT: return E(0) > E(1) ? 1.0f : 0.0f; case OP_ADD: return E(0) + E(1); case OP_SUB: return E(0) - E(1); case OP_UMINUS: return - E(0); case OP_MUL: return E(0) * E(1); case OP_DIV: { float q = E(1); if (q == 0.0f) { warning_msg("cost function division by zero"); return 1.0f; } return E(0) / q; } default: ; } } } else if (is_var(f)) { unsigned idx = to_var(f)->get_idx(); if (idx < m_num_args) return m_args[m_num_args - idx - 1]; } warning_msg("cost function evaluation error"); return 1.0f; }
static CSLbool numeqrr(Lisp_Object a, Lisp_Object b) { return numeq2(numerator(a), numerator(b)) && numeq2(denominator(a), denominator(b)); }
void Field::put(Sink & sink1) const { Sink sink2(sink1.outputFunction("List",2L)); sink1 << numerator().asInt() << denominator().asInt(); };
std::vector<TupletInfo> detectTuplets( const std::multimap<ReducedFraction, MidiChord>::iterator &startBarChordIt, const std::multimap<ReducedFraction, MidiChord>::iterator &endBarChordIt, const ReducedFraction &startBarTick, const ReducedFraction &barFraction, std::multimap<ReducedFraction, MidiChord> &chords, const ReducedFraction &basicQuant, int barIndex) { const auto divLengths = Meter::divisionsOfBarForTuplets(barFraction); std::vector<TupletInfo> tuplets; int id = 0; const auto tol = basicQuant / 2; for (const auto &divLen: divLengths) { const auto tupletNumbers = findTupletNumbers(divLen, barFraction); const auto div = barFraction / divLen; const int divCount = div.numerator() / div.denominator(); for (int i = 0; i != divCount; ++i) { const auto startDivTime = startBarTick + divLen * i; const auto endDivTime = startBarTick + divLen * (i + 1); // check which chords can be inside tuplet period // [startDivTime - tol, endDivTime] const auto startDivTimeWithTol = qMax(startBarTick, startDivTime - tol); auto startDivChordIt = MChord::findFirstChordInRange(startDivTimeWithTol, endDivTime, startBarChordIt, endBarChordIt); if (startDivChordIt == endBarChordIt) continue; Q_ASSERT_X(!startDivChordIt->second.isInTuplet, "MIDI tuplets: findTuplets", "Tuplet chord has been already used"); // end iterator, as usual, point to the next - invalid chord auto endDivChordIt = chords.lower_bound(endDivTime); if (!isNextBarOwnershipOk(startDivChordIt, endDivChordIt, chords, barIndex)) continue; // try different tuplets, nested tuplets are not allowed // here chords from next bar can be captured // if their on time < next bar start for (const auto &tupletNumber: tupletNumbers) { if (!isTupletLenAllowed(divLen, tupletNumber, startDivChordIt, endDivChordIt, basicQuant)) { continue; } auto tupletInfo = findTupletApproximation(divLen, tupletNumber, basicQuant, startDivTime, startDivChordIt, endDivChordIt); const auto &opers = midiImportOperations.data()->trackOpers; const int currentTrack = midiImportOperations.currentTrack(); if (opers.simplifyDurations.value(currentTrack)) { if (!haveChordsInTheMiddleBetweenTupletChords( startDivChordIt, endDivChordIt, tupletInfo)) { detectStaccato(tupletInfo); } } tupletInfo.sumLengthOfRests = findSumLengthOfRests(tupletInfo, startBarTick); if (!isTupletAllowed(tupletInfo)) continue; tupletInfo.id = id++; tuplets.push_back(tupletInfo); // tuplet found } // next tuplet type } } return tuplets; }
int Fraction::compare(const Fraction& right) const { return numerator() * right.denominator() - denominator() * right.numerator(); // Return the numerator of the difference }
static Lisp_Object plusrr(Lisp_Object a, Lisp_Object b) /* * Adding two ratios involves some effort to keep the result in * lowest terms. */ { Lisp_Object nil = C_nil; Lisp_Object na = numerator(a), nb = numerator(b); Lisp_Object da = denominator(a), db = denominator(b); Lisp_Object w = nil; push5(na, nb, da, db, nil); #define g stack[0] #define db stack[-1] #define da stack[-2] #define nb stack[-3] #define na stack[-4] g = gcd(da, db); nil = C_nil; if (exception_pending()) goto fail; /* * all the calls to quot2() in this procedure are expected - nay required - * to give exact integer quotients. */ db = quot2(db, g); nil = C_nil; if (exception_pending()) goto fail; g = quot2(da, g); nil = C_nil; if (exception_pending()) goto fail; na = times2(na, db); nil = C_nil; if (exception_pending()) goto fail; nb = times2(nb, g); nil = C_nil; if (exception_pending()) goto fail; na = plus2(na, nb); nil = C_nil; if (exception_pending()) goto fail; da = times2(da, db); nil = C_nil; if (exception_pending()) goto fail; g = gcd(na, da); nil = C_nil; if (exception_pending()) goto fail; na = quot2(na, g); nil = C_nil; if (exception_pending()) goto fail; da = quot2(da, g); nil = C_nil; if (exception_pending()) goto fail; w = make_ratio(na, da); /* * All the goto statements and the label seem a fair way of expressing * the common action that has to be taken if an error or interrupt is * detected during any of the intermediate steps here. Anyone who * objects can change it if they really want... */ fail: popv(5); return w; #undef na #undef nb #undef da #undef db #undef g }
double float_of_number(Lisp_Object a) /* * Return a (double precision) floating point value for the given Lisp * number, or 0.0 in case of trouble. This is often called in circumstances * where I already know the type of its argument and so its type-dispatch * is unnecessary - in doing so I am trading off performance against * code repetition. */ { if (is_fixnum(a)) return (double)int_of_fixnum(a); #ifdef COMMON else if (is_sfloat(a)) { Float_union w; w.i = a - TAG_SFLOAT; return (double)w.f; } #endif else if (is_bfloat(a)) { int32_t h = type_of_header(flthdr(a)); switch (h) { #ifdef COMMON case TYPE_SINGLE_FLOAT: return (double)single_float_val(a); #endif case TYPE_DOUBLE_FLOAT: return double_float_val(a); #ifdef COMMON case TYPE_LONG_FLOAT: return (double)long_float_val(a); #endif default: return 0.0; } } else { Header h = numhdr(a); int x1; double r1; switch (type_of_header(h)) { case TYPE_BIGNUM: r1 = bignum_to_float(a, length_of_header(h), &x1); return ldexp(r1, x1); #ifdef COMMON case TYPE_RATNUM: { int x2; Lisp_Object na = numerator(a); a = denominator(a); if (is_fixnum(na)) r1 = float_of_number(na), x1 = 0; else r1 = bignum_to_float(na, length_of_header(numhdr(na)), &x1); if (is_fixnum(a)) r1 = r1 / float_of_number(a), x2 = 0; else r1 = r1 / bignum_to_float(a, length_of_header(numhdr(a)), &x2); /* Floating point overflow can only arise in this ldexp() */ return ldexp(r1, x1 - x2); } #endif default: /* * If the value was non-numeric or a complex number I hand back 0.0, * and since I am supposed to have checked the object type already * this OUGHT not to arrive - bit raising an exception seems over-keen. */ return 0.0; } } }
void tex::flush_node_list(ptr p) { ptr q; while (p != null) { q = link(p); if (is_char_node(p)) { free_avail(p); } else { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case UNSET_NODE: flush_node_list(list_ptr(p)); free_node(p, BOX_NODE_SIZE); goto done; case RULE_NODE: free_node(p, RULE_NODE_SIZE); goto done; case INS_NODE: flush_node_list(ins_ptr(p)); delete_glue_ref(split_top_ptr(p)); free_node(p, INS_NODE_SIZE); goto done; case WHATSIT_NODE: free_whatsit(p); goto done; case GLUE_NODE: fast_delete_glue_ref(glue_ptr(p)); if (leader_ptr(p) != null) flush_node_list(leader_ptr(p)); break; case KERN_NODE: case MATH_NODE: case PENALTY_NODE: break; case LIGATURE_NODE: flush_node_list(lig_ptr(p)); break; case MARK_NODE: delete_token_ref(mark_ptr(p)); break; case DISC_NODE: flush_node_list(pre_break(p)); flush_node_list(post_break(p)); break; case ADJUST_NODE: flush_node_list(adjust_ptr(p)); break; case STYLE_NODE: free_node(p, STYLE_NODE_SIZE); goto done; case CHOICE_NODE: flush_node_list(display_mlist(p)); flush_node_list(text_mlist(p)); flush_node_list(script_mlist(p)); flush_node_list(script_script_mlist(p)); free_node(p, STYLE_NODE_SIZE); goto done; case ORD_NOAD: case OP_NOAD: case BIN_NOAD: case REL_NOAD: case OPEN_NOAD: case CLOSE_NOAD: case PUNCT_NOAD: case INNER_NOAD: case RADICAL_NOAD: case OVER_NOAD: case UNDER_NOAD: case VCENTER_NOAD: case ACCENT_NOAD: if (math_type(nucleus(p)) >= SUB_BOX) flush_node_list(math_link(nucleus(p))); if (math_type(supscr(p)) >= SUB_BOX) flush_node_list(math_link(supscr(p))); if (math_type(subscr(p)) >= SUB_BOX) flush_node_list(math_link(subscr(p))); if (type(p) == RADICAL_NOAD) free_node(p, RADICAL_NOAD_SIZE); else if (type(p) == ACCENT_NOAD) free_node(p, ACCENT_NOAD_SIZE); else free_node(p, NOAD_SIZE); goto done; case LEFT_NOAD: case RIGHT_NOAD: free_node(p, NOAD_SIZE); goto done; case FRACTION_NOAD: flush_node_list(math_link(numerator(p))); flush_node_list(math_link(denominator(p))); free_node(p, FRACTION_NOAD_SIZE); goto done; default: confusion("flushing"); break; } free_node(p, SMALL_NODE_SIZE); done:; } p = q; } }
Polynom::Polynom(const string str) { int tmp, tmp1, tmp2; coefficients.clear(); if (str.length() < 8) throw(invalid_argument("incorrect number input. You can try help\n")); for (auto i = 0; i < str.length(); i++) if (!isdigit(str[i]) && str[i] != 'x' && str[i] != '^' && str[i] != '+' && str[i] != '-' && str[i] != '/' && str[i] != '(' && str[i] != ')') throw(invalid_argument("incorrect number input. You can try help\n")); tmp = 0; if (str[0] == '-' || str[0] == '+') tmp++; do { tmp1 = str.find("(", tmp); if (tmp1 != tmp) throw(invalid_argument("incorrect number input. You can try help\n")); tmp = ++tmp1; while (tmp < str.size() && isdigit(str[tmp])) tmp++; if (tmp == tmp1) throw(invalid_argument("incorrect number input. You can try help\n")); if (tmp != -1) { tmp1 = str.find("/", tmp); if (tmp1 == -1 || (tmp1 - tmp) != 0) throw(invalid_argument("incorrect number input. You can try help\n")); tmp = ++tmp1; while (tmp < str.size() && isdigit(str[tmp])) tmp++; if (tmp == tmp1) throw(invalid_argument("incorrect number input. You can try help\n")); tmp1 = str.find(")", tmp); if (tmp1 == -1 || (tmp1 - tmp) != 0) throw(invalid_argument("incorrect number input. You can try help\n")); tmp = ++tmp1; tmp1 = str.find("x^", tmp); if (tmp1 == -1 || (tmp1 - tmp) != 0) throw(invalid_argument("incorrect number input. You can try help\n")); tmp1 += 2; while (tmp1 < str.size() && isdigit(str[tmp1])) tmp1++; if (tmp == tmp1) throw(invalid_argument("incorrect number input. You can try help\n")); if (tmp1 == str.size()) break; tmp2 = tmp = tmp1; tmp = str.find("+", tmp); tmp1 = str.find("-", tmp1); if (tmp == -1 && tmp1 == -1) throw(invalid_argument("incorrect number input. You can try help\n")); if (tmp == -1) tmp = tmp1; if (tmp1 < tmp) tmp = tmp1; if ((tmp - tmp2) != 0) throw(invalid_argument("incorrect number input. You can try help\n")); tmp++; } else throw(invalid_argument("incorrect number input. You can try help\n")); } while (true); MegaNatural lastCoef,b_lastCoef; int sign; MegaRational coef(); bool first = true; int pos = 0; do { if (first) { first = false; if (str[0] == '-') sign = -1; else sign = 1; MegaInteger numerator(getNextNum(str, pos)); numerator = numerator*(MegaInteger)(-1); MegaNatural denominator(getNextNum(str, pos)); coefficients.push_front(MegaRational(numerator, denominator)); lastCoef = getNextNum(str, pos); continue; } tmp = str.find("+", pos); tmp1 = str.find("-", pos); if (tmp == -1 && tmp1 == -1) break; if (tmp != -1 && tmp1 != -1) if (tmp < tmp1) sign = 1; else sign = -1; if (tmp == -1) sign = -1; if (tmp1 == -1) sign = 1; MegaInteger numerator(getNextNum(str, pos)); numerator = numerator*(MegaInteger) (-1); MegaNatural denominator(getNextNum(str, pos)); coefficients.push_front(MegaRational(numerator, denominator)); b_lastCoef = lastCoef; lastCoef = getNextNum(str, pos); if (lastCoef >= b_lastCoef) { coefficients.clear(); coefficients.resize(0); throw(invalid_argument("incorrect number input. You can try help\n")); } else { while ((b_lastCoef - (MegaNatural) 1) > lastCoef) { b_lastCoef = b_lastCoef - (MegaNatural) 1; coefficients.push_front(MegaRational()); } } } while (pos < str.size()); while (lastCoef>(MegaNatural)0) { lastCoef = lastCoef - (MegaNatural)1; coefficients.push_front(MegaRational()); } }
rational& rational::operator-=(rational const& rhs) { numerator_ = numerator() * rhs.denominator() - rhs.numerator() * denominator(); denominator_ *= rhs.denominator(); reduce(); return *this; }
std::shared_ptr<AVFrame> make_av_video_frame(const core::const_frame& frame, const core::video_format_desc& format_desc) { auto av_frame = alloc_frame(); auto pix_desc = frame.pixel_format_desc(); auto planes = pix_desc.planes; auto format = pix_desc.format; const auto sar = boost::rational<int>(format_desc.square_width, format_desc.square_height) / boost::rational<int>(format_desc.width, format_desc.height); av_frame->sample_aspect_ratio = {sar.numerator(), sar.denominator()}; av_frame->width = format_desc.width; av_frame->height = format_desc.height; switch (format) { case core::pixel_format::rgb: av_frame->format = AVPixelFormat::AV_PIX_FMT_RGB24; break; case core::pixel_format::bgr: av_frame->format = AVPixelFormat::AV_PIX_FMT_BGR24; break; case core::pixel_format::rgba: av_frame->format = AVPixelFormat::AV_PIX_FMT_RGBA; break; case core::pixel_format::argb: av_frame->format = AVPixelFormat::AV_PIX_FMT_ARGB; break; case core::pixel_format::bgra: av_frame->format = AVPixelFormat::AV_PIX_FMT_BGRA; break; case core::pixel_format::abgr: av_frame->format = AVPixelFormat::AV_PIX_FMT_ABGR; break; case core::pixel_format::gray: av_frame->format = AVPixelFormat::AV_PIX_FMT_GRAY8; break; case core::pixel_format::ycbcr: { int y_w = planes[0].width; int y_h = planes[0].height; int c_w = planes[1].width; int c_h = planes[1].height; if (c_h == y_h && c_w == y_w) av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV444P; else if (c_h == y_h && c_w * 2 == y_w) av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV422P; else if (c_h == y_h && c_w * 4 == y_w) av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV411P; else if (c_h * 2 == y_h && c_w * 2 == y_w) av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV420P; else if (c_h * 2 == y_h && c_w * 4 == y_w) av_frame->format = AVPixelFormat::AV_PIX_FMT_YUV410P; break; } case core::pixel_format::ycbcra: av_frame->format = AVPixelFormat::AV_PIX_FMT_YUVA420P; break; } FF(av_frame_get_buffer(av_frame.get(), 32)); // TODO (perf) Avoid extra memcpy. for (int n = 0; n < planes.size(); ++n) { for (int y = 0; y < av_frame->height; ++y) { std::memcpy(av_frame->data[n] + y * av_frame->linesize[n], frame.image_data(n).data() + y * planes[n].linesize, planes[n].linesize); } } return av_frame; }
Lisp_Object negate(Lisp_Object a) { #ifdef COMMON Lisp_Object nil; /* needed for errexit() */ #endif switch ((int)a & TAG_BITS) { case TAG_FIXNUM: { int32_t aa = -int_of_fixnum(a); /* * negating the number -#x8000000 (which is a fixnum) yields a value * which just fails to be a fixnum. */ if (aa != 0x08000000) return fixnum_of_int(aa); else return make_one_word_bignum(aa); } #ifdef COMMON case TAG_SFLOAT: { Float_union aa; aa.i = a - TAG_SFLOAT; aa.f = (float) (-aa.f); return (aa.i & ~(int32_t)0xf) + TAG_SFLOAT; } #endif case TAG_NUMBERS: { int32_t ha = type_of_header(numhdr(a)); switch (ha) { case TYPE_BIGNUM: return negateb(a); #ifdef COMMON case TYPE_RATNUM: { Lisp_Object n = numerator(a), d = denominator(a); push(d); n = negate(n); pop(d); errexit(); return make_ratio(n, d); } case TYPE_COMPLEX_NUM: { Lisp_Object r = real_part(a), i = imag_part(a); push(i); r = negate(r); pop(i); errexit(); push(r); i = negate(i); pop(r); errexit(); return make_complex(r, i); } #endif default: return aerror1("bad arg for minus", a); } } case TAG_BOXFLOAT: { double d = float_of_number(a); return make_boxfloat(-d, type_of_header(flthdr(a))); } default: return aerror1("bad arg for minus", a); } }
static CSLbool numeqsr(Lisp_Object a, Lisp_Object b) /* * Here I will rely somewhat on the use of IEEE floating point values * (an in particular the weaker supposition that I have floating point * with a binary radix). Then for equality the denominator of b must * be a power of 2, which I can test for and then account for. */ { Lisp_Object nb = numerator(b), db = denominator(b); double d = float_of_number(a), d1; int x; int32_t dx, w, len; uint32_t u, bit; /* * first I will check that db (which will be positive) is a power of 2, * and set dx to indicate what power of two it is. * Note that db != 0 and that one of the top two words of a bignum * must be nonzero (for normalisation) so I end up with a nonzero * value in the variable 'bit' */ if (is_fixnum(db)) { bit = int_of_fixnum(db); w = bit; if (w != (w & (-w))) return NO; /* not a power of 2 */ dx = 0; } else if (is_numbers(db) && is_bignum(db)) { int32_t lenb = (bignum_length(db)-CELL-4)/4; bit = bignum_digits(db)[lenb]; /* * I need to cope with bignums where the leading digits is zero because * the 0x80000000 bit of the next word down is 1. To do this I treat * the number as having one fewer digits. */ if (bit == 0) bit = bignum_digits(db)[--lenb]; w = bit; if (w != (w & (-w))) return NO; /* not a power of 2 */ dx = 31*lenb; while (--lenb >= 0) /* check that the rest of db is zero */ if (bignum_digits(db)[lenb] != 0) return NO; } else return NO; /* Odd - what type IS db here? Maybe error. */ if ((bit & 0xffffU) == 0) dx += 16, bit = bit >> 16; if ((bit & 0xff) == 0) dx += 8, bit = bit >> 8; if ((bit & 0xf) == 0) dx += 4, bit = bit >> 4; if ((bit & 0x3) == 0) dx += 2, bit = bit >> 2; if ((bit & 0x1) == 0) dx += 1; if (is_fixnum(nb)) { double d1 = (double)int_of_fixnum(nb); /* * The ldexp on the next line could potentially underflow. In that case C * defines that the result 0.0 be returned. To avoid trouble I put in a * special test the relies on that fact that a value represented as a rational * would not have been zero. */ if (dx > 10000) return NO; /* Avoid gross underflow */ d1 = ldexp(d1, (int)-dx); return (d == d1 && d != 0.0); } len = (bignum_length(nb)-CELL-4)/4; if (len == 0) /* One word bignums can be treated specially */ { int32_t v = bignum_digits(nb)[0]; double d1; if (dx > 10000) return NO; /* Avoid gross underflow */ d1 = ldexp((double)v, (int)-dx); return (d == d1 && d != 0.0); } d1 = frexp(d, &x); /* separate exponent from mantissa */ if (d1 == 1.0) d1 = 0.5, x++; /* For Zortech */ dx += x; /* adjust to allow for the denominator */ d1 = ldexp(d1, (int)(dx % 31)); /* can neither underflow nor overflow here */ /* * At most 3 words in the bignum may contain nonzero data - I subtract * the (double) value of those bits off and check that (a) the floating * result left is zero and (b) there are no more bits left. */ dx = dx / 31; if (dx != len) return NO; w = bignum_digits(nb)[len]; d1 = (d1 - (double)w) * TWO_31; u = bignum_digits(nb)[--len]; d1 = (d1 - (double)u) * TWO_31; if (len > 0) { u = bignum_digits(nb)[--len]; d1 = d1 - (double)u; } if (d1 != 0.0) return NO; while (--len >= 0) if (bignum_digits(nb)[len] != 0) return NO; return YES; }
void normalize() { numerator_ = numerator(); denominator_ = denominator(); }
void arctan(void) { double d; save(); p1 = pop(); if (car(p1) == symbol(TAN)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { errno = 0; d = atan(p1->u.d); if (errno) stop("arctan function error"); push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } if (isnegative(p1)) { push(p1); negate(); arctan(); negate(); restore(); return; } // arctan(sin(a) / cos(a)) ? if (find(p1, symbol(SIN)) && find(p1, symbol(COS))) { push(p1); numerator(); p2 = pop(); push(p1); denominator(); p3 = pop(); if (car(p2) == symbol(SIN) && car(p3) == symbol(COS) && equal(cadr(p2), cadr(p3))) { push(cadr(p2)); restore(); return; } } // arctan(1/sqrt(3)) -> pi/6 if (car(p1) == symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), -1, 2)) { push_rational(1, 6); push(symbol(PI)); multiply(); restore(); return; } // arctan(1) -> pi/4 if (equaln(p1, 1)) { push_rational(1, 4); push(symbol(PI)); multiply(); restore(); return; } // arctan(sqrt(3)) -> pi/3 if (car(p1) == symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), 1, 2)) { push_rational(1, 3); push(symbol(PI)); multiply(); restore(); return; } push_symbol(ARCTAN); push(p1); list(2); restore(); }
float to_float() { return static_cast<float>(numerator()) / denominator(); }