Пример #1
0
bigInt myPow(bigInt base, bigInt exp)
{
	// возведение base в степень exp
// такое имя потому, что есть стандартная функция с таким же именем,
// а в си плоховато с перегрузкой функций
	bigInt res = createFromInt(1); // сюда будет записан результат
	bigInt zero = createFromInt(0);
	bigInt i = copy(exp); // сколько раз результат необходимо умножить на exp
	bigInt minusOne = createFromInt(-1); // -1

	// пока количество необходимых умножений больше нуля
	while (compare(i, zero) > 0)
	{
		// res = res * base
		bigInt tmp = mul(res, base);
		free(res.digits);
		res = tmp;

		// смысл следующих трёх строчек: i = i -1
		tmp = sumAndSub(i, minusOne); // складываем i и (-1), т.е. tmp = i - 1
		free(i.digits); // очищаем память
		i = tmp;
	}

	// очищаем память
	free(i.digits);
	free(zero.digits);
	free(minusOne.digits);

	return res;
}
Пример #2
0
bigInt powMod(bigInt base, bigInt exp, bigInt modul)
{
    // возведение base в степень exp по модулю modul
    // используется алгоритм быстрого возведения в степень
	bigInt res = createFromInt(1); // сюда будет записан результат
	bigInt zero = createFromInt(0);
    bigInt two = createFromInt(2);
    bigInt b = copy(exp);
    bigInt a = copy(base);

    while (compare(b, zero) > 0)
	{
        if (odd(b))
        {
            // res = (res * a) % modul;
            // tmp = res * base
            bigInt tmp = mul(res, a);

            // res = tmp % modul
            bigInt modRem; // сюда запишем остаток от деления
            bigInt tmp2 = dividing(tmp, modul, &modRem);
            free(tmp2.digits);
            free(tmp.digits);
            free(res.digits);
            res = modRem;
        }
        // a = (a*a) % modul
        bigInt tmp = mul(a, a);
        free(a.digits);

        bigInt modRem; // сюда запишем остаток от деления
        bigInt tmp2 = dividing(tmp, modul, &modRem);
        free(tmp2.digits);
        free(tmp.digits);
        a = modRem;

        // b = b /2
        tmp = dividing(b, two, &modRem);
        free(b.digits);
        free(modRem.digits);
        b = tmp;
	}
	// очищаем память
    free(b.digits);
    free(zero.digits);
    free(two.digits);
	return res;
}
Пример #3
0
int saveTobinarFile(const char* filename, bigInt A)
{
	// будем считать, что в бинарный файл необходимо записать число по основанию 256
	// то есть необходимо перейти от BASE к 256 (256 - потому что максимальное значение байта - 255)
	// для этого надо находить остатки от деления на 256
	// пока число не уменьшиться до 0
	// возвращаем 0 в случае успешной записи
	// не 0 - в случае ошибки

	FILE* pfDestination = fopen(filename, "w+b");
	if (!pfDestination)
		return 1;

	struct bigInt tmp = copy(A); // число, которое будем делить на 256
	tmp.sign = 0; // не будем обращать внимания на знак
	bigInt zero = createFromInt(0);
	bigInt b256 = createFromInt(256);

	// пока число не станет равным 0
	while (compare(tmp, zero) != 0)
	{
		bigInt ost; // куда будет записан остаток от деления на 256

		// tmp = tmp / 256
		bigInt tmp2 = dividing(tmp, b256, &ost);
		free(tmp.digits);
		tmp = tmp2;

		// теперь в ost очередной остаток от деления на 256
		// запишем его в файл

		fwrite((char*)&ost.digits[0], sizeof(unsigned char), 1, pfDestination);
		free(ost.digits);
	}

	free(tmp.digits);
	free(b256.digits);
	free(zero.digits);

	fclose(pfDestination);
	return 0;
}
Пример #4
0
 KernelVariable::uniquePtr KernelVariable::createFromVec2i(const std::string& varName, const Vec2i& vec)
 {
     return createFromInt(varName, (int*)&vec, 2);
 }
Пример #5
0
bigInt getFrombinarFile(const char* filename)
{
	// будем считать, что в бинарном файле записаны разряды числа по модулю 256.
	// таким образом, чтобы считать число из бинарного файла необходимо каждый байт
	// умножить на 256 ^ i, где i - позиция байта в файле и всё это сложить

	FILE* pfSource = fopen(filename, "r+b");
	if (!pfSource)
	{
		// если файл не открылся
		bigInt res;
		res.sizeNum = 0;
		res.sign = 0;
		res.digits = NULL;
		return res;
	}

	// узнаем размер файла
	fseek(pfSource, 0, SEEK_END);
	int filesizeNum = ftell(pfSource);
	fseek(pfSource, 0, SEEK_SET);

	// считываем содержимое файла
	unsigned char* fileContent = (unsigned char*)malloc(filesizeNum);
	fread((char*) fileContent, sizeof(unsigned char), filesizeNum, pfSource);
	fclose(pfSource);

	bigInt pow256 = createFromInt(1); // здесь будет 256 ^ i
	bigInt res = createFromInt(0); // здесь сформируем результат
	bigInt b256 = createFromInt(256); // число 256

	// цикл для всех байтов в файле
	int i;
	for (i = 0; i < filesizeNum; i++)
	{
		bigInt fi = createFromInt(fileContent[i]); // получили очередной байт файла

		// res = res + pow256 * fi;

		// tmp = fi * 256 ^ i
		bigInt tmp = mul(fi, pow256);
		free(fi.digits);

		// tmp2 = res + tmp = res + fi * 256^i
		bigInt tmp2 = sumAndSub(res, tmp);
		free(tmp.digits);
		free(res.digits);
		res = tmp2; // res = res + pow256 * fi;

		// pow256 = pow256*256
		tmp = mul(pow256, b256);
		free(pow256.digits);
		pow256 = tmp;
	}

	free(fileContent);
	free(pow256.digits);
	free(b256.digits);

	return res;
}
Пример #6
0
bigInt dividing(bigInt A, bigInt B, bigInt* ost)
{
	*ost = copy(A);
	ost->sign = 0;
	bigInt divider = copy(B);
	divider.sign = 0;
	if (1 == divider.sizeNum)
	{
		if (divider.digits[0] == 0)
		{
			ost->sizeNum = 0;
			ost->sign = 0;
			ost->digits = NULL;
			bigInt a;
			a.sizeNum = 0;
			a.sign = 0;
			a.digits = NULL;
			free(divider.digits);
			return a;
		}
	}
	if (compare(*ost, divider) < 0)
	{
		ost->sign = A.sign;
		bigInt res;
		res.sign = 0;
		res.sizeNum = 1;
		res.digits = (unsigned int*)malloc((res.sizeNum)*sizeof(unsigned int));
		res.digits[0] = 0;
		free(divider.digits);
		return res;
	}
	if (divider.sizeNum == 1)
	{
		bigInt res;
		res.sizeNum = A.sizeNum;
		res.digits = (unsigned int*)malloc((res.sizeNum)*sizeof(unsigned int));
		unsigned long long int carry = 0;
		int i;
		for (i = A.sizeNum - 1; i >= 0; i--)
		{
			unsigned long long int temp = carry;
			temp *= BASE;
			temp += A.digits[i];
			res.digits[i] = temp / divider.digits[0];
			carry = (unsigned long long int)  temp - (unsigned long long int) res.digits[i] * (unsigned long long int) divider.digits[0];
		}
		ost->sign = (A.sign != B.sign);
		if (ost->sizeNum > 0)
		free(ost->digits);
		ost->sizeNum = 1;
		ost->digits = (unsigned int*)malloc((1)*sizeof(unsigned int));
		ost->digits[0] = carry;
		*ost = DelZeros(*ost);
		res.sign = (A.sign != B.sign);
		res = DelZeros(res);
		free(divider.digits);
		return res;
	}
	bigInt res;
	res.sign = 0;
	res.sizeNum = A.sizeNum - B.sizeNum + 1;
	res.digits = (unsigned int*)malloc((res.sizeNum)*sizeof(unsigned int));

	int i;
	for (i = A.sizeNum - B.sizeNum + 1; i != 0; i--)
	{
		long long int qGuessMax = BASE; // для того, чтобы qGuessMin могло быть равно BASE - 1
		long long int qGuessMin = 0;
		long long int qGuess = qGuessMax;
		while (qGuessMax - qGuessMin > 1)
		{
			qGuess = (qGuessMax + qGuessMin) / 2;
			bigInt qGuesslargeNum = createFromInt(qGuess);
			bigInt tmp = mul(divider, qGuesslargeNum);
			free(qGuesslargeNum.digits);
			tmp = shiftLeft(tmp, i - 1);
			if (compare(tmp, *ost) > 0)
				qGuessMax = qGuess;
			else
				qGuessMin = qGuess;
			free(tmp.digits);
		}
		bigInt qGuessMinlargeNum = createFromInt(qGuessMin);
		bigInt tmp = mul(divider, qGuessMinlargeNum);
		free(qGuessMinlargeNum.digits);
		tmp = shiftLeft(tmp, i - 1);
		bigInt tmpRem = copy(*ost);
		bigInt minusTmp = minus(tmp);
		free(ost->digits);
		*ost = sumAndSub(tmpRem, minusTmp);
		free(tmpRem.digits);
		free(minusTmp.digits);
		free(tmp.digits);
		res.digits[i - 1] = qGuessMin;
	}
	res.sign = (A.sign != B.sign);
	ost->sign = (A.sign != B.sign);
	*ost = DelZeros(*ost);
	res = DelZeros(res);
	free(divider.digits);
	return res;
}