整数除法还有这么一手,学习!

引用:http://www.xuebuyuan.com/521526.html

要求:如何用移位和加减实现除以3的操作,在此略微扩充一下,实现无符号整数除法,但是返回值也为无符号整型。

利用魔数。代码如下。

#include <iostream>

using namespace std;

int divide3(int a)
{
	return ((__int64)a * 0xAAAAAAAB) >>33;
}

int main()
{
	int in;
	cin>>in;
	cout<<divide3(in)<<endl;
	return 0;
}

方法中的魔数的原理是为了用乘法实现32位被除数的除法运算,编译器会为被除数乘上一个32位的倒数,就形成了一个64位的数,其中低32位是余数,高32位为我们需要的结果,以下是一些常用的魔数,例如0xAAAAAAAB就代表2/3,0xCCCCCCCD代表4/5等等,具体可以在网上搜索相关内容。利用魔数除以5的代码如下。

#include <iostream>

using namespace std;

int divide5(int a)
{
	return ((__int64)a * 0xCCCCCCCD) >>34;
}

int main()
{
	int in;
	cin>>in;
	cout<<divide5(in)<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
整数除法可以通过手动模拟长除法的方法来实现。下面是一个简单的实现示例: 假设我们要计算 123456789 / 987654321。 首先,我们从左到右扫描被除数,找到一个与除数相等或大于除数的部分。 在本例中,我们可以找到 12345 >= 9876。 然后,我们将被除数的这一部分除以除数,得到商和余数。 在本例中,我们可以计算出商为 1,余数为 2469。 接下来,我们将商放在答案的相应位置上,并将余数与下一位被除数相加。 在本例中,我们将商 1 放在答案的第一位上,然后将余数 2469 和下一位被除数 5 相加,得到新的被除数 24695。 我们重复以上步骤,直到被除数的所有位都被处理完毕。 最终,我们得到商为 0,余数为 123456789。 因此,123456789 / 987654321 的结果为 0,余数为 123456789。 具体实现可以参考如下代码: ```c #include <stdio.h> #include <string.h> #define MAX_LEN 1000 // 最大位数 // 大整数结构体 typedef struct { int len; // 数字长度 int num[MAX_LEN]; // 数字数组,从低位到高位存储 } BigInt; // 大整数除法函数 void BigIntDivide(BigInt dividend, BigInt divisor, BigInt *quotient, BigInt *remainder) { // 初始化商和余数 quotient->len = 0; memset(quotient->num, 0, sizeof(quotient->num)); remainder->len = 0; memset(remainder->num, 0, sizeof(remainder->num)); // 将被除数从低位到高位扫描 for (int i = dividend.len - 1; i >= 0; i--) { // 将余数左移一位,加上当前位被除数 for (int j = remainder->len - 1; j >= 0; j--) { remainder->num[j + 1] = remainder->num[j]; } remainder->num[0] = dividend.num[i]; remainder->len++; // 判断余数是否大于等于除数 int cmp = 0; while (remainder->len >= divisor.len) { cmp = memcmp(remainder->num, divisor.num, divisor.len * sizeof(int)); if (cmp >= 0) { break; } // 如果余数小于除数,将余数右移一位 for (int j = 0; j < remainder->len - 1; j++) { remainder->num[j] = remainder->num[j + 1]; } remainder->len--; remainder->num[remainder->len] = 0; } // 如果余数大于等于除数,计算商和余数 if (cmp >= 0) { // 计算当前位的商和余数 int q = 0; BigInt tmp; tmp.len = 0; memset(tmp.num, 0, sizeof(tmp.num)); for (int j = remainder->len - 1; j >= 0; j--) { tmp.num[j] = remainder->num[j]; tmp.len++; if (cmp >= 0) { q++; cmp = memcmp(tmp.num, divisor.num, divisor.len * sizeof(int)); if (cmp >= 0) { memset(tmp.num, 0, sizeof(tmp.num)); tmp.len = 0; } } } // 将商放在答案的相应位置上 quotient->num[quotient->len++] = q; // 更新余数 memcpy(remainder->num, tmp.num, tmp.len * sizeof(int)); remainder->len = tmp.len; } } // 答案的高位可能为 0,需要去掉前导零 while (quotient->len > 1 && quotient->num[quotient->len - 1] == 0) { quotient->len--; } while (remainder->len > 1 && remainder->num[remainder->len - 1] == 0) { remainder->len--; } } int main() { BigInt dividend = {9, {1, 2, 3, 4, 5, 6, 7, 8, 9}}; BigInt divisor = {9, {9, 8, 7, 6, 5, 4, 3, 2, 1}}; BigInt quotient, remainder; BigIntDivide(dividend, divisor, &quotient, &remainder); printf("%d / %d = ", dividend.num, divisor.num); for (int i = quotient.len - 1; i >= 0; i--) { printf("%d", quotient.num[i]); } printf(" (remainder = "); for (int i = remainder.len - 1; i >= 0; i--) { printf("%d", remainder.num[i]); } printf(")\n"); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值