Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
	// 文字列を速力に変換する
	inline Speed operator| (const string& str, ToSpeed_helper) {
		switch (str | to_i()) {
		case 10: return kSpeedHigh;
		case 5:  return kSpeedLow;
		default: return kSpeedNone;
		}
	}
Ejemplo n.º 3
0
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;
    }
}
Ejemplo n.º 4
0
inline
ximpl_integer::ff_to_i_r_t_
to_i(
    LARGE_INTEGER const&    value
)
{
    return to_i(value.QuadPart);
}
Ejemplo n.º 5
0
inline
ximpl_integer::ff_to_i_r_t_
to_i(
    LARGE_INTEGER const&    value
,   int                     minimumWidth
)
{
    return to_i(value.QuadPart, minimumWidth);
}
Ejemplo n.º 6
0
/** 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);
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
    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;
        }
    }
Ejemplo n.º 10
0
  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;
  }
Ejemplo n.º 11
0
// 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;
	}
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
// 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;
}
Ejemplo n.º 14
0
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;
}