除法的商数和余数大整数与一个大整数的乘积
Quotient and remainder for division a product of big integers by a big integer
long long signed A, B, C;
或
long long unsigned A, B, C;
我需要计算表达式A * B / C
的商和余数,其中A
, B
, C
是大整数,因此A * B
的乘积导致溢出,A < C
和B < C
。禁止使用浮点数和使用第三方库。怎样才能做到呢?
A*B/C
的余数等于A/C
和B/C
余数的乘积再模C
//编辑:Ups,没有看到条件A<C
, B<C
。在这种情况下,尝试这样做:
tmp = A;
for (var i = 1; i<=B; i++)
{
if (tmp + A == overflow || tmp + A >= C)
tmp -= C;
tmp += A;
}
结果tmp
应该是您所寻找的余数。只要所有的输入都是正的,我们在有符号的情况下这样做就可以。也许它也可以用于unsigned,但没有检查。
当然你需要一些花哨的函数来检查oveflow
条件。
对于商,你可以求出A/C
,然后乘以B
,对吗?
用任意大整数做乘法其实很简单:你只要像在学校时那样在纸上手抄就行了。但是,与以10为基数的十进制数字不同,您可以使用字节或整数。
例如:A = 12340;
B = 56789;
aa = new byte[] { A/256, A%256 };
bb = new byte[] { B/256, B%256 };
现在您可以循环遍历数组并以更小的步骤执行乘法。
我相信一个好的开始应该是使用c/c++与gmp。GMP是一个任意精度的库,它为任意精度实现了所有这些操作。
编辑:(没有第三方库)
我对它的第二个想法(gmp之后)是质因数分解。你需要一个算法。你用因子分解、b因子分解和c因子分解创建一个向量,它们有因子分解的素数列表。然后将A/B中的质数与C中的质数进行比较,并开始将它们从A/B和C向量中删除。在测试完所有元素之后,将vector的所有元素相乘,然后进行常规除法。
对于没有64位算术的32位数字的乘法,Schrage有一个方法。也许你可以把它扩展到64位乘法。
例如:
typedef long long ll;
const ll base = 1000*1000*1000; // 10^9 for example, could be also 1<<32
// or smth convenient, the goal is to store
// the numbers and a result in 'base'-based numerical system
// to avoid overflow
pair<ll, ll> p1 = make_pair( A/base, A%base ); // store the numbers in
pair<ll, ll> p2 = make_pair( B/base, B%base ); // 'base'-based numerical system
vector<ll> v1(4);
v1[ 0 ] = p1.second * p2.second;
v1[ 1 ] = p1.first * p2.second + v1[ 0 ] / base; v1[ 0 ] %= base;
v1[ 2 ] = v1[ 1 ] / base; v1[ 1 ] %= base;
vector<ll> v2(4);
v2[ 1 ] = p1.second * p2.first;
v2[ 2 ] = p1.first * p2.first + v2[ 1 ] / base; v2[ 1 ] %= base;
v2[ 3 ] = v2[ 1 ] / base; v2[ 2 ] %= base;
ll tmp = 0;
for( i = 0; i < 4; ++i )
{
v1[ i ] = v1[ i ] + v2[ i ] + tmp;
tmp = v1[ i ] / base;
v1[ i ] %= base;
}
现在v1存储以10^9为基数的A*B的值。剩下的就是小心地将其除为C,这是一个相当简单的数学挑战:)
必须将A和B拆分为其上下32位部分
A = Au * (1<<32) + Al
B = Bu * (1<<32) + Bl
(计算为Au=A>>32; Al=A&(1<<(32)-1;
),并分别考虑这些部分的产品:
A*B = Au*Bu * (1<<64) + (Au*Bl+Al*Bu) * (1<<32) + Al*Bl
接下来,您必须将这些项中的每一项除以C,并将商和余数相加(小心避免溢出!)。特别是Au*Bu>C是不可能的,因为你最初的要求。
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 当我们从/tp地址中添加/减去一个整数时会发生什么
- 如何将一个数组值合并为一个整数c++
- 为什么有时我输入一个整数,程序将第一个输入的数字打印成十进制数?
- 给定一个整数数组,需要在Max_Heap上运行操作。得到错误"segmentation fault",有什么想法吗?(C++)
- 我可以将迭代器递增一个整数吗?
- 有没有办法生成一个包含平方的序列,这些平方加起来就是一个整数平方?
- 我正在尝试制作一个程序,在添加 n 天(整数)后告诉一个人什么是一天(例如星期一等)
- 为什么将两个浮点数相加会得到一个整数C++?
- 编写一个读取五个整数并执行一些任务的C++程序
- 如果我们在其中输入一个整数,则字符会给出整数作为输出,但是当分配给它一个整数时,这不会发生。为什么?
- 给枚举一个整数,并在 C++ 中将其相关值作为字符串获取
- 我需要编写一个程序来读取一个文件,该文件将输出所有唯一的整数,如果已经看到整数,它将被关闭
- 按升序输出整数时,将最后一个整数放在新行上
- 编写一个程序,提示用户输入一个整数,然后输出数字的单个数字和数字的总和
- 我在c++中遇到了一个奇怪的错误,其中一个计算2个小整数加法的语句溢出到一个长值中
- 如何在C++中将一个值拆分为一个十进制整数
- 给定一个整数 N>0,区间 [0, 2^N) 中有多少个整数正好有 N-1 个设置位?编写一个返回正确答案的简短函数
- 我必须更改我的数字最后一个数字和第一个数字,但不要使用仅带有整数或循环的函数.例如从 12345 到 52341
- 将整数范围映射到另一个范围