cons_t* parse_exact_real(const char* sc, int radix) { if ( radix != 10 ) raise(parser_exception( "Only reals with decimal radix are supported")); /* * Since the real is already in string form, we can simply turn it into a * rational number. */ char *s = strdup(sc); char *d = strchr(s, '.'); *d = '\0'; const char* left = s; const char* right = d+1; int decimals = strlen(right); /* * NOTE: If we overflow here, we're in big trouble. * TODO: Throw an error if we overflow. Or just implement bignums. */ rational_t r; r.numerator = to_i(left, radix)*pow10(decimals) + to_i(right, radix); r.denominator = pow10(decimals); free(s); return rational(r, true); }
// 文字列を速力に変換する inline Speed operator| (const string& str, ToSpeed_helper) { switch (str | to_i()) { case 10: return kSpeedHigh; case 5: return kSpeedLow; default: return kSpeedNone; } }
int main(int argc, char *argv[]) { int column = 0; int space_run = 0; int c; if (argc > 1) { argv++; while (argv[0]) { if (argv[0][0] == '-') to_i(&argv[0][1], &tab_start); if (argv[0][0] == '+') to_i(&argv[0][1], &tab_width); argv++; } } while ((c = getchar()) != EOF) { if (c == ' ') { ++space_run; } else if (c == '\n') { column = -1; space_run = 0; putchar(c); } else { if (space_run == 1) { putchar(' '); space_run = 0; } while (space_run > 0) { int start_of_space_run = column - space_run; int next_stop = next_tab_stop(start_of_space_run); if (next_stop <= column) { putchar('\t'); space_run -= next_stop - start_of_space_run; } else { for (; space_run > 0; space_run--) putchar(' '); } } putchar(c); } ++column; } }
inline ximpl_integer::ff_to_i_r_t_ to_i( LARGE_INTEGER const& value ) { return to_i(value.QuadPart); }
inline ximpl_integer::ff_to_i_r_t_ to_i( LARGE_INTEGER const& value , int minimumWidth ) { return to_i(value.QuadPart, minimumWidth); }
/** Inserts the string form of a LARGE_INTEGER value * * \ingroup group__inserters * * \param value The LARGE_INTEGER value to be converted to string form * \param minimumWidth The minimum width of the result. If negative, the * integer is aligned to the left of the resulting field * \param precision The minimum number of digits in the field, which will * result in zero-padding if the given integer has fewer digits * * \return An instance of an insertable type containing the string form of * the integer * * \pre abs(minimumWidth) < 512 * \pre decimalPlaces <= minimumWidth */ inline ximpl_integer::ff_to_i_r_t_ to_i( LARGE_INTEGER const& value , int minimumWidth = ximpl_integer::default_width_sentinel_() , int precision = ximpl_integer::default_precision_sentinel_() ) { return to_i(value.QuadPart, minimumWidth, precision); }
rational_t to_r(const char* sc, int radix) { char *s = strdup(sc); // form: <integer>/<integer> char *d = strchr(s, '/'); if ( d == NULL ) raise(runtime_exception("Rational number has no divisor")); *d = '\0'; char *numerator = s; char *denominator = d+1; rational_t r; r.numerator = to_i(numerator, radix); r.denominator = to_i(denominator, radix); free(s); return r; }
LongNumber LongNumber::operator+(const LongNumber& other) { int max_size = max(number.size(), other.number.size()); int carry = 0; long sum = 0;//Kristian: Каква е причината да ползваш long? LongNumber result(0); for (/*Kristian: Каква е причината да ползваш long? max_size по дефиниция не може*/long i = 1; i <= max_size; i++) { sum = to_i(*this, number.size() - i) + to_i(other, other.number.size() - i) + carry; if(carry) carry = 0; if(sum >= 10) carry = 1; result.number.insert(result.number.begin(), '0' + sum%10); } if(carry) result.number.insert(0, "1"); return result; }
void Number::trim(unsigned precision/* = s_default_precision*/) { switch (type()) { case Number::INTEGER: break; case Number::FLOATING: { assign(str(precision, std::ios_base::fixed)); integer_type i = to_i(); floating_type f = static_cast<floating_type>(i); if (f == get_f()) assign(i); } break; case Number::RATIONAL: { rational_type r = get_r(); if (b_mp::denominator(r) == 1) assign(b_mp::numerator(r)); } break; #ifndef PMP_DISABLE_VECTOR case Number::VECTOR: for (size_t i = 0; i < get_v().size(); ++i) get_v()[i].trim(precision); if (size() == 1) assign(get_v()[0]); break; #endif default: assert(0); break; } }
Integer* String::to_inum_prim(STATE, Fixnum* base, Object* strict) { Integer* val = to_i(state, base, strict); if(val->nil_p()) return (Integer*)Primitives::failure(); return val; }
// Finds the position of a number in a string, searching from // the right, meeting: // - not part of a known suffix if there is another number to // the left of it // - prefixed by at least one capital 'A'-'Z' or '_' // If none is found, both *num_start and *num_end will be returned as 0. static void find_number(const char* s, int s_len, int* num_start, int* num_end) { int result, dig_start, dig_end, found_num, search_more; int next_dig_start, next_dig_end; *num_start = 0; *num_end = 0; if (s_len >= 13 && !strncmp("_DSP48A1_SITE", &s[s_len-13], 13)) s_len -= 13; else if (s_len >= 15 && !strncmp("_DSP48A1_B_SITE", &s[s_len-15], 15)) s_len -= 15; result = find_rightmost_num(s, s_len, &dig_start, &dig_end); if (!result) return; // If the found number is not part of a potential // suffix, we can take it. found_num = to_i(&s[dig_start], dig_end-dig_start); // The remaining suffixes all reach the right end of // the string, so if our digits don't, we can take them. if (dig_end < s_len) { *num_start = dig_start; *num_end = dig_end; return; } search_more = 0; // _ if (dig_start >= 2 && s[dig_start-1] == '_' && ((s[dig_start-2] >= 'A' && s[dig_start-2] <= 'Z') || (s[dig_start-2] >= '0' && s[dig_start-2] <= '9'))) search_more = 1; // _S0 else if (found_num == 0 && dig_start >= 3 && s[dig_start-1] == 'S' && s[dig_start-2] == '_' && ((s[dig_start-3] >= 'A' && s[dig_start-3] <= 'Z') || (s[dig_start-3] >= '0' && s[dig_start-3] <= '9'))) search_more = 1; // _N3 else if (found_num == 3 && dig_start >= 3 && s[dig_start-1] == 'N' && s[dig_start-2] == '_' && ((s[dig_start-3] >= 'A' && s[dig_start-3] <= 'Z') || (s[dig_start-3] >= '0' && s[dig_start-3] <= '9'))) search_more = 1; // _INT0 _INT1 _INT2 _INT3 else if ((found_num >= 0 && found_num <= 3) && dig_start >= 5 && s[dig_start-1] == 'T' && s[dig_start-2] == 'N' && s[dig_start-3] == 'I' && s[dig_start-4] == '_' && ((s[dig_start-5] >= 'A' && s[dig_start-5] <= 'Z') || (s[dig_start-5] >= '0' && s[dig_start-5] <= '9'))) search_more = 1; if (!search_more || !find_rightmost_num(s, dig_start, &next_dig_start, &next_dig_end)) { *num_start = dig_start; *num_end = dig_end; } else { *num_start = next_dig_start; *num_end = next_dig_end; } }
static int sort_lines(const void* a, const void* b) { const char* _a, *_b; int a_word_beg, a_word_end, b_word_beg, b_word_end; int a_num, b_num, a_num_start, b_num_start, a_num_end, b_num_end; int num_result, result, suffix_result; _a = a; _b = b; // find the first non-matching word a_word_beg = 0; b_word_beg = 0; next_unequal_word(_a, a_word_beg, &a_word_beg, &a_word_end, _b, b_word_beg, &b_word_beg, &b_word_end); if (a_word_end-a_word_beg <= 0) { if (b_word_end-b_word_beg <= 0) return 0; return -1; } if (b_word_end-b_word_beg <= 0) { if (a_word_end-a_word_beg <= 0) return 0; return 1; } // first try to find 2 numbers find_number(&_a[a_word_beg], a_word_end-a_word_beg, &a_num_start, &a_num_end); find_number(&_b[b_word_beg], b_word_end-b_word_beg, &b_num_start, &b_num_end); // if we cannot find both numbers, return a regular // string comparison over the entire word if (a_num_end <= a_num_start || b_num_end <= b_num_start) { result = str_cmp(&_a[a_word_beg], a_word_end-a_word_beg, &_b[b_word_beg], b_word_end-b_word_beg); if (!result) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); exit(0); } return result; } // A number must always be prefixed by at least one character. if (!a_num_start || !b_num_start) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); exit(0); } // otherwise compare the string up to the 2 numbers, // if it does not match return that result result = str_cmp(&_a[a_word_beg], a_num_start, &_b[b_word_beg], b_num_start); if (result) return result; a_num_start += a_word_beg; a_num_end += a_word_beg; b_num_start += b_word_beg; b_num_end += b_word_beg; if (a_num_end > a_word_end || b_num_end > b_word_end) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); fprintf(stderr, "sort_line_a: %s", _a); fprintf(stderr, "sort_line_b: %s", _b); exit(1); } if ((a_word_end-a_num_end == 0 || is_known_suffix(&_a[a_num_end], a_word_end-a_num_end)) && (b_word_end-b_num_end == 0 || is_known_suffix(&_b[b_num_end], b_word_end-b_num_end))) { // known suffix comes before number suffix_result = str_cmp(&_a[a_num_end], a_word_end-a_num_end, &_b[b_num_end], b_word_end-b_num_end); if (suffix_result) return suffix_result; } a_num = to_i(&_a[a_num_start], a_num_end-a_num_start); b_num = to_i(&_b[b_num_start], b_num_end-b_num_start); num_result = a_num-b_num; // if the non-known suffixes don't match, return numeric result // if numbers are not equal, otherwise suffix result suffix_result = str_cmp(&_a[a_num_end], a_word_end-a_num_end, &_b[b_num_end], b_word_end-b_num_end); if (suffix_result) { if (num_result) return num_result; return suffix_result; } // Should be impossible that both the number result and // suffix result are equal. How can the entire word then // be unequal? if (!num_result) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); fprintf(stderr, "sort_line_a: %s", _a); fprintf(stderr, "sort_line_b: %s", _b); exit(1); } // find second non-equal word next_unequal_word(_a, a_word_end, &a_word_beg, &a_word_end, _b, b_word_end, &b_word_beg, &b_word_end); if (a_word_end <= a_word_beg || b_word_end <= b_word_beg) return num_result; // if no numbers in second non-equal words, fall back // to numeric result of first word find_number(&_a[a_word_beg], a_word_end-a_word_beg, &a_num_start, &a_num_end); find_number(&_b[b_word_beg], b_word_end-b_word_beg, &b_num_start, &b_num_end); if (a_num_end <= a_num_start || b_num_end <= b_num_start) return num_result; // A number must always be prefixed by at least one character. if (!a_num_start || !b_num_start) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); exit(0); } // If the prefix string of the second word does not // match, fall back to numeric result of first word. result = str_cmp(&_a[a_word_beg], a_num_start, &_b[b_word_beg], b_num_start); if (result) return num_result; a_num_start += a_word_beg; a_num_end += a_word_beg; b_num_start += b_word_beg; b_num_end += b_word_beg; if (a_num_end > a_word_end || b_num_end > b_word_end) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); exit(0); } // if there are known suffixes in second non-equal // words, compare those first if ((a_word_end-a_num_end == 0 || is_known_suffix(&_a[a_num_end], a_word_end-a_num_end)) && (b_word_end-b_num_end == 0 || is_known_suffix(&_b[b_num_end], b_word_end-b_num_end))) { // known suffix comes before number suffix_result = str_cmp(&_a[a_num_end], a_word_end-a_num_end, &_b[b_num_end], b_word_end-b_num_end); if (suffix_result) return suffix_result; } // otherwise fall back to numeric result of first word return num_result; }
// Finds the positions of two non-equal numbers that must meet // the following two criteria: // - prefixed by at least one capital 'A'-'Z' or '_' // - suffixed by matching or empty strings static void find_non_matching_number(const char* a, int a_len, const char* b, int b_len, int* ab_start, int* a_end, int* b_end) { int a_o, b_o, digit_start, a_num, b_num; *ab_start = -1; a_o = 0; // from the left side, search for the first non-matching // character while (a[a_o] == b[a_o] && a_o < a_len && a_o < b_len) a_o++; // if the strings match entirely, return if (a_o >= a_len && a_o >= b_len) return; // If neither of the non-matching characters is a digit, return if ((a[a_o] < '0' || a[a_o] > '9') && (b[a_o] < '0' || b[a_o] > '9')) return; // go back to beginning of numeric section // (first and second must be identical going backwards) while (a_o && a[a_o-1] >= '0' && a[a_o-1] <= '9') a_o--; // If there is not at least one capital 'A'-'Z' or '_' // before the number, return if (!a_o || ((a[a_o-1] < 'A' || a[a_o-1] > 'Z') && a[a_o-1] != '_')) return; // now skip over all digits in left and right string digit_start = a_o; while (a[a_o] >= '0' && a[a_o] <= '9' && a_o < a_len) a_o++; b_o = digit_start; while (b[b_o] >= '0' && b[b_o] <= '9' && b_o < b_len) b_o++; // there must be at least one digit on each side if (a_o <= digit_start || b_o <= digit_start) return; a_num = to_i(&a[digit_start], a_o-digit_start); b_num = to_i(&b[digit_start], b_o-digit_start); if (a_num == b_num) { fprintf(stderr, "Strange parsing issue with '%.*s' and '%.*s'\n", a_len, a, b_len, b); return; } // the trailing part after the two numbers must match if (a_len - a_o != b_len - b_o) return; if ((a_len - a_o) && strncmp(&a[a_o], &b[b_o], a_len-a_o)) return; // some known suffixes include numbers and must never be // part of merging if (a_len - a_o == 0) { // _S0 _N3 if (a_o > 3 && ((a[a_o-3] == '_' && a[a_o-2] == 'S' && a[a_o-1] == '0') || (a[a_o-3] == '_' && a[a_o-2] == 'N' && a[a_o-1] == '3'))) return; // _INT0 _INT1 _INT2 _INT3 if (a_o > 5 && a[a_o-5] == '_' && a[a_o-4] == 'I' && a[a_o-3] == 'N' && a[a_o-2] == 'T' && a[a_o-1] >= '0' && a[a_o-1] <= '3') return; } *ab_start = digit_start; *a_end = a_o; *b_end = b_o; }
static int merge_line(struct line_buf* first_l, struct line_buf* second_l) { int first_o, second_o, fs_start, f_end, s_end, first_num, second_num; int first_eow, second_eow, f_start, s_start; int left_start, left_end, left_num; if (!first_l->buf[0] || !second_l->buf[0]) return 0; // go through word by word, find first non-equal word first_o = 0; second_o = 0; while (1) { next_word(first_l->buf, first_o, &first_o, &first_eow); next_word(second_l->buf, second_o, &second_o, &second_eow); if (first_eow <= first_o || second_eow <= second_o) return 0; if (first_eow-first_o != second_eow-second_o || strncmp(&first_l->buf[first_o], &second_l->buf[second_o], first_eow-first_o)) break; first_o = first_eow; second_o = second_eow; } // non-matching number inside? fs_start = -1; find_non_matching_number(&first_l->buf[first_o], first_eow-first_o, &second_l->buf[second_o], second_eow-second_o, &fs_start, &f_end, &s_end); if (fs_start == -1) return 0; // no: cannot merge f_start = first_o+fs_start; f_end += first_o; s_start = second_o+fs_start; s_end += second_o; first_o = first_eow; second_o = second_eow; // in sequence? if not, cannot merge second_num = to_i(&second_l->buf[s_start], s_end-s_start); if (first_l->sequence_size) { if (first_l->left_digit_start_o < 0) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); return -1; } // We must be looking at the same digit, for example // if we have a sequence SW2M0:3, and now the second // line is SW4M0 - the '4' must not be seen as a // continuation of the '3'. if (s_start != first_l->left_digit_start_o) return 0; if (second_num != first_l->left_digit_base + first_l->sequence_size + 1) return 0; first_num = -1; // to suppress compiler warning } else { first_num = to_i(&first_l->buf[f_start], f_end-f_start); if (second_num != first_num + 1) return 0; } // find next non-equal word while (1) { next_word(first_l->buf, first_o, &first_o, &first_eow); next_word(second_l->buf, second_o, &second_o, &second_eow); if (first_eow <= first_o && second_eow <= second_o) { // reached end of line if (first_l->sequence_size) { if (first_l->right_digit_start_o != -1) return 0; first_l->sequence_size++; } else { first_l->left_digit_start_o = f_start; first_l->left_digit_end_o = f_end; first_l->left_digit_base = first_num; first_l->right_digit_start_o = -1; first_l->sequence_size = 1; } second_l->buf[0] = 0; return 0; } if (first_eow <= first_o || second_eow <= second_o) return 0; if (first_eow-first_o != second_eow-second_o || strncmp(&first_l->buf[first_o], &second_l->buf[second_o], first_eow-first_o)) break; first_o = first_eow; second_o = second_eow; } // now we must find a second number matching the sequence left_start = f_start; left_end = f_end; left_num = first_num; // non-matching number inside? fs_start = -1; find_non_matching_number(&first_l->buf[first_o], first_eow-first_o, &second_l->buf[second_o], second_eow-second_o, &fs_start, &f_end, &s_end); if (fs_start == -1) return 0; // no: cannot merge f_start = first_o+fs_start; f_end += first_o; s_start = second_o+fs_start; s_end += second_o; first_o = first_eow; second_o = second_eow; // in sequence? if not, cannot merge second_num = to_i(&second_l->buf[s_start], s_end-s_start); if (first_l->sequence_size) { if (first_l->right_digit_start_o < 0 || second_num != first_l->right_digit_base + first_l->sequence_size + 1) return 0; } else { first_num = to_i(&first_l->buf[f_start], f_end-f_start); if (second_num != first_num + 1) return 0; } // find next non-equal word while (1) { next_word(first_l->buf, first_o, &first_o, &first_eow); next_word(second_l->buf, second_o, &second_o, &second_eow); if (first_eow <= first_o && second_eow <= second_o) { // reached end of line if (first_l->sequence_size) first_l->sequence_size++; else { first_l->left_digit_start_o = left_start; first_l->left_digit_end_o = left_end; first_l->left_digit_base = left_num; first_l->right_digit_start_o = f_start; first_l->right_digit_end_o = f_end; first_l->right_digit_base = first_num; first_l->sequence_size = 1; } second_l->buf[0] = 0; return 0; } if (first_eow <= first_o || second_eow <= second_o) return 0; if (first_eow-first_o != second_eow-second_o || strncmp(&first_l->buf[first_o], &second_l->buf[second_o], first_eow-first_o)) break; first_o = first_eow; second_o = second_eow; } // found another non-matching word, cannot merge return 0; }