Beispiel #1
0
void code_editor_widget::select_token(const std::string& row, int& begin_row, int& end_row, int& begin_col, int& end_col)
{
	std::pair<int,int> key(begin_row, begin_col);
	if(bracket_match_.count(key)) {
		begin_row = bracket_match_.find(key)->second.front().first;
		begin_col = bracket_match_.find(key)->second.front().second;
		end_row = bracket_match_.find(key)->second.back().first;
		end_col = bracket_match_.find(key)->second.back().second+1;
		return;
	}

	text_editor_widget::select_token(row, begin_row, end_row, begin_col, end_col);

	std::string token(row.begin() + begin_col, row.begin() + end_col);
	
	boost::regex numeric_regex("-?\\d+(\\.\\d+)?", boost::regex::perl);
	std::cerr << "token: (" << token << ")\n";
	if(boost::regex_match(token.c_str(), numeric_regex)) {

		const decimal current_value(decimal::from_string(token));
		if(current_value <= 10000000 && current_value >= -10000000) {
			slider_.reset(new slider(200, boost::bind(&code_editor_widget::on_slider_move, this, _1)));
			slider_decimal_ = std::count(token.begin(), token.end(), '.') ? true : false;
			slider_magnitude_ = (abs(current_value.as_int())+1) * 5;
	
			const decimal slider_value = (current_value - decimal::from_int(-slider_magnitude_)) / decimal::from_int(slider_magnitude_*2);
			slider_->set_position(slider_value.as_float());

			std::pair<int,int> pos = char_position_on_screen(begin_row, (begin_col+end_col)/2);

			row_slider_ = begin_row;
			begin_col_slider_ = begin_col;
			end_col_slider_ = end_col;

			int x = pos.second - slider_->width()/2;
			int y = pos.first + 20 - slider_->height();
			if(x < 10) {
				x = 10;
			}

			if(x > width() - slider_->width()) {
				x = width() - slider_->width();
			}

			if(y < 20) {
				y += 60;
			}

			if(y > height() - slider_->height()) {
				y = height() - slider_->height();
			}
	
			slider_->set_loc(x, y);
		}
	}
}
Beispiel #2
0
void decimal::suma(const decimal &sum)
{
    // Por cada cifra del decimal, empezando por el final:
    //  1. Sumamos ambos numeros.
    //  2. Si la suma pasa de 10 acarreamos para la siguiente cifra, y restamos
    //      10 a la cifra actual.

    bool acarreo = false;

    for(unsigned int i = 0; i < cifs; ++i) {
        uint8_t op1 = this->get_cifra(i);
        uint8_t op2 = sum.get_cifra(i);
        uint8_t op3 = op1 + op2;

        if(acarreo) ++op3;

        if(op3 >= 10) {
            acarreo = true;
            op3 -= 10;
        }
        else {
            acarreo = false;
        }

        // Control para el overflow.
        if(acarreo && (i == cifs - 1))
            this->set_cifra(10, i);
        else
            this->set_cifra(op3, i);
    }
}
Beispiel #3
0
void decimal::resta(const decimal &res)
{
    // Por cada cifra del decimal, empezando por el final:
    //  1. Comprobamos si operador 1 es mayor o igual operador 2.
    //  2. Si lo es, restamos. Si no, añadimos 10, indicando acarreo para el siguiente, y restamos.

    bool acarreo = false;

    for(unsigned int i = 0; i < cifs; ++i) {
        uint8_t op1 = this->get_cifra(i);
        uint8_t op2 = res.get_cifra(i);

        if(acarreo) ++op2;

        if(op1 < op2) {
            op1 += 10;
            acarreo = true;
        }
        else {
            acarreo = false;
        }

        int op3 = op1 - op2;

        this->set_cifra(op3, i);
    }
}
Beispiel #4
0
bool operator==(const decimal &a, const decimal &b)
{
    // 1. Comparamos signos. Si son diferentes devolvemos falso.
    // 2. Cambiamos el tamaño de b para que coincida con el de a.
    // 3. Comparamos cifra a cifra.

    if(a.is_negative() != b.is_negative()) return false;

    decimal t(b);
    t.resize(a.cifs, a.decs);

    for(int i = 0; i < static_cast<int>(a.long_buffer); ++i)
        if(a.buffer[i] != t.buffer[i])
            return false;

    return true;
}
Beispiel #5
0
inline decimal operator*(const decimal& a, const decimal& b) {
	const int64_t va = a.value() > 0 ? a.value() : -a.value();
	const int64_t vb = b.value() > 0 ? b.value() : -b.value();

	const int64_t ia = va/DECIMAL_PRECISION;
	const int64_t ib = vb/DECIMAL_PRECISION;

	const int64_t fa = va%DECIMAL_PRECISION;
	const int64_t fb = vb%DECIMAL_PRECISION;

	const decimal result = decimal(ia*ib*DECIMAL_PRECISION + fa*ib + fb*ia + (fa*fb)/DECIMAL_PRECISION);
	if(a.value() < 0 && b.value() > 0 || b.value() < 0 && a.value() > 0) {
		return -result;
	} else {
		return result;
	}
}
Beispiel #6
0
decimal operator/(const decimal& a, const decimal& b)
{
	int64_t va = a.value() > 0 ? a.value() : -a.value();
	int64_t vb = b.value() > 0 ? b.value() : -b.value();

	if(va == 0) {
		return a;
	}

	int64_t orders_of_magnitude_shift = 0;
	const int64_t target_value = DECIMAL(10000000000000);

	while(va < target_value) {
		va *= DECIMAL(10);
		++orders_of_magnitude_shift;
	}

	const int64_t target_value_b = DECIMAL(1000000);

	while(vb > target_value_b) {
		vb /= DECIMAL(10);
		++orders_of_magnitude_shift;
	}

	int64_t value = (va/vb);

	while(orders_of_magnitude_shift > 6) {
		value /= DECIMAL(10);
		--orders_of_magnitude_shift;
	}

	while(orders_of_magnitude_shift < 6) {
		value *= DECIMAL(10);
		++orders_of_magnitude_shift;
	}

	const decimal result(decimal::from_raw_value(value));
	if(a.value() < 0 && b.value() > 0 || b.value() < 0 && a.value() > 0) {
		return -result;
	} else {
		return result;
	}
}
Beispiel #7
0
bool operator<=(const decimal &a, const decimal &b)
{
    // 1. Comparamos signos. Si son distintos, el negativo es el menor.
    // 2. Cambiamos el tamaño de b para que coincida con el de a.
    // 3. Comparamos cifra a cifra, y devolvemos en consecuencia.

    if(a.is_negative() != b.is_negative())
        return a.is_negative();

    decimal t(b);
    t.resize(a.cifs, a.decs);

    bool    a_menor = false,
            iguales = true;

    for(int i = a.cifs - 1; i >= 0; --i) {
        if(a.get_cifra(i) != t.get_cifra(i)) {
            iguales = false;
            if(a.get_cifra(i) < t.get_cifra(i)) {
                a_menor = true;
            }
            break;
        }
    }

    if(iguales)
        return true;

    // Invertimos el resultado si a y b son negativos.
    return a.is_negative() ? !a_menor : a_menor;
}
Beispiel #8
0
decimal decimal::operator -=(const decimal& b)
{
	if (b.isZero()) {
		return *this;
	}
	decimal& a = *this;
	const size_t w = a.length();
	if (b.length() > w) {
		throw underflow_error("Negative values not allowed");
	}
	bool borrow = false;
	for (size_t i = 0; i < w; i++) {
		digit d = a[i] - b[i] - (borrow ? 1 : 0);
		borrow = d < 0;
		a[i] = borrow ? 10 + d : d;
	}
	if (borrow) {
		throw underflow_error("Negative values not allowed");
	}
	remove_lz();
	return *this;
}
Beispiel #9
0
decimal decimal::operator +=(const decimal& b)
{
	if (isZero()) {
		*this = b;
		return *this;
	} else if (b.isZero()) {
		return *this;
	}
	decimal& a = *this;
	const size_t w = max(a.length(), b.length());
	digits.resize(w + 1);
	bool carry = false;
	for (size_t i = 0; i < w; i++) {
		digit d = a[i] + b[i] + (carry ? 1 : 0);
		carry = d >= 10;
		a[i] = carry ? d - 10 : d;
	}
	if (carry) {
		a[w] = 1;
	} else {
		digits.resize(w);
	}
	return *this;
}
Beispiel #10
0
decimal decimal::operator *(const decimal& value) const
{
	const decimal& a = length() <= value.length() ? *this : value;
	const decimal& b = length() > value.length() ? *this : value;
	if (a.isZero()) {
		return decimal(0);
	} else if (a.isUnity()) {
		return b;
	}
	decimal c;
	const auto as = a.length();
	const auto bs = b.length();
	c.digits.resize(as + bs);
	for (size_t i = 0; i < as; i++) {
		const digit ad = a[i];
		if (ad == 0) {
			continue;
		}
		decimal tmp;
		tmp.digits.resize(bs + i + 1);
		digit carry = 0;
		for (size_t j = 0; j < bs; j++) {
			digit d = b[j] * ad + carry;
			carry = d / 10;
			tmp[j + i] = d - (carry * 10);
		}
		if (carry) {
			tmp[bs + i] = carry;
		} else {
			tmp.digits.resize(bs + i);
		}
		c += tmp;
	}
	c.remove_lz();
	return c;
}
Beispiel #11
0
char decimal::relation_to(const decimal& b) const
{
	const decimal& a = *this;
	const auto as = a.length();
	const auto bs = b.length();
	if (as > bs) {
		return +1;
	} else if (bs > as) {
		return -1;
	}
	for (auto i = as; i > 0; i--) {
		digit d = a[i - 1] - b[i - 1];
		if (d > 0) {
			return +1;
		} else if (d < 0) {
			return -1;
		}
	}
	return 0;
}
Beispiel #12
0
	explicit variant(decimal d) : type_(VARIANT_TYPE_DECIMAL), decimal_value_(d.value()) {}
Beispiel #13
0
decimal decimal::parallel_multiply(const decimal& l, const decimal& r)
{
	const decimal& a = l.length() <= r.length() ? l : r;
	const decimal& b = l.length() > r.length() ? l : r;
	if (a.isZero()) {
		return decimal(0);
	} else if (a.isUnity()) {
		return b;
	}
	const auto as = a.length();
	const auto bs = b.length();
	const size_t cores = std::thread::hardware_concurrency();
	const size_t workers = min<size_t>(cores, (as / 1000));
	if (workers == 0) {
		return l * r;
	}
	decimal result;
	result.digits.resize(as + bs);
	mutex mx;
	function<int(size_t, size_t)> partial_product = [&a, &b, as, bs, &mx, &result] (size_t begin, size_t end) {
		decimal c;
		c.digits.resize(as + bs);
		decimal tmp;
		tmp.digits.reserve(bs + end + 1);
		for (size_t i = begin; i < end; i++) {
			const digit ad = a[i];
			if (ad == 0) {
				continue;
			}
			fill(tmp.digits.begin(), tmp.digits.end(), 0);
			tmp.digits.resize(bs + i + 1);
			digit carry = 0;
			for (size_t j = 0; j < bs; j++) {
				digit d = b[j] * ad + carry;
				carry = d / 10;
				tmp[j + i] = d - (carry * 10);
			}
			if (carry) {
				tmp[bs + i] = carry;
			} else {
				tmp.digits.resize(bs + i);
			}
			c += tmp;
		}
		lock_guard<mutex> lock(mx);
		result += c;
		return 0;
	};
	vector<future<int>> futures;
	futures.reserve(workers);
	for (size_t worker = 0; worker < workers; worker++) {
		const auto begin = (as * worker) / workers;
		const auto end = (as * (worker + 1)) / workers;
		futures.emplace_back(async(std::launch::async, partial_product, begin, end));
	}
	for (size_t worker = 0; worker < workers; worker++) {
		auto& future = futures[worker];
		future.get();
	}
	result.remove_lz();
	return result;
}
Beispiel #14
0
void code_editor_widget::select_token(const std::string& row, int& begin_row, int& end_row, int& begin_col, int& end_col)
{
	std::pair<int,int> key(begin_row, begin_col);
	if(bracket_match_.count(key)) {
		begin_row = bracket_match_.find(key)->second.front().first;
		begin_col = bracket_match_.find(key)->second.front().second;
		end_row = bracket_match_.find(key)->second.back().first;
		end_col = bracket_match_.find(key)->second.back().second+1;
		return;
	}

	text_editor_widget::select_token(row, begin_row, end_row, begin_col, end_col);

	std::string token(row.begin() + begin_col, row.begin() + end_col);
	
	boost::regex numeric_regex("-?\\d+(\\.\\d+)?", boost::regex::perl);
	std::cerr << "token: (" << token << ")\n";
	if(boost::regex_match(token.c_str(), numeric_regex)) {

		const decimal current_value(decimal::from_string(token));
		if(current_value <= 10000000 && current_value >= -10000000) {
			slider_.reset(new slider(200, boost::bind(&code_editor_widget::on_slider_move, this, _1)));
			slider_decimal_ = std::count(token.begin(), token.end(), '.') ? true : false;
			slider_magnitude_ = (abs(current_value.as_int())+1) * 5;
	
			const decimal slider_value = (current_value - decimal::from_int(-slider_magnitude_)) / decimal::from_int(slider_magnitude_*2);
			slider_->set_position(slider_value.as_float());

			slider_range_.clear();
			slider_labels_.clear();
			if(current_value > 0) {
				slider_range_.push_back(slider_range(0.0, 0.1, -current_value*5, -current_value));
				slider_range_.push_back(slider_range(0.1, 0.2, -current_value, decimal(0)));
				slider_range_.push_back(slider_range(0.2, 0.3, decimal(0), current_value));
				slider_range_.push_back(slider_range(0.3, 0.5, decimal(0), current_value));
				slider_range_.push_back(slider_range(0.5, 0.7, current_value, 2*current_value));
				slider_range_.push_back(slider_range(0.7, 0.9, 2*current_value, 5*current_value));
				slider_range_.push_back(slider_range(0.9, 1.0, 5*current_value, 10*current_value));
				slider_range_.push_back(slider_range(1.0, 2.0, 10*current_value, 20*current_value));
				slider_->set_position(0.5);
			} else {
				slider_range_.push_back(slider_range(0.0, 0.5, current_value*2, decimal(0)));
				slider_range_.push_back(slider_range(0.5, 1.0, decimal(0), -current_value*2));
				slider_range_.push_back(slider_range(1.0, 2.0, -current_value*2, -current_value*4));
				slider_->set_position(0.25);
			}

			std::pair<int,int> pos = char_position_on_screen(begin_row, (begin_col+end_col)/2);

			row_slider_ = begin_row;
			begin_col_slider_ = begin_col;
			end_col_slider_ = end_col;

			int x = pos.second - slider_->width()/2;
			int y = pos.first + 20 - slider_->height();
			if(x < 10) {
				x = 10;
			}

			if(x > width() - slider_->width()) {
				x = width() - slider_->width();
			}

			if(y < 20) {
				y += 60;
			}

			if(y > height() - slider_->height()) {
				y = height() - slider_->height();
			}
	
			slider_->set_loc(x, y);

			foreach(slider_range& r, slider_range_) {
				slider_labels_.push_back(widget_ptr(new gui::label(formatter() << r.target_begin, 10)));
				slider_labels_.back()->set_loc(x + slider_->width()*r.begin - slider_labels_.back()->width()/2, y);
			}
		}
Beispiel #15
0
inline bool operator<=(const decimal& a, const decimal& b) {
	return a.value() <= b.value();
}
Beispiel #16
0
inline decimal operator-(const decimal& a, const decimal& b) {
	return decimal(a.value() - b.value());
}