FJYBioCS 2021-11-06 13:55 采纳率: 100%
浏览 150
已结题

C语言通过位运算实现取模运算

这是一道课后习题,原题如下:

定义函数unsigned mod(unsigned a, unsigned b, unsigned c); 功能是计算并返回ab%c的结果。要求考试a, b, c的范围是大于0且小于 2^31,程序不能使用64位整型(如:long long类型或__int64)求解。
问题:a
b可能溢出(超出32位unsigned int型的表示范围)。为解决此问题,可用如下算法。
设unsigned型变量b的每个二进制位为xi (i=0,1, …, 31),i=0为最低位,i=31为最高位,则

img


上式中,axi的结果或者为a或者为0;
2运算可用左移1位操作实现(小于2^31的整数2结果一定小于2^32, 不会发生溢出);
%c的结果是小于c的,而c小于2^31,它与a求和也不会发生溢出。
编写完整程序,用迭代法实现上述算法。
要求测试b的每个二进制xi位为1或0的操作必须采用位运算实现。
输入提示:"Input unsigned integer numbers a, b, c:\n"
输入格式:"%u %u %u"
输出格式:"%u
%u%%%u=%u\n"

我的代码如下:

#pragma warning(disable:4996)
#include <stdio.h>

unsigned mod(unsigned a, unsigned b, unsigned c) {
    unsigned sum = a * ((b >> 30) & 1);
    for (int i = 29; i >= 0; i--) {
        sum = (sum << 1) % c + a * ((b >> i) & 1);
    }
    return sum % c;
}

int main() {
        //此部分用于实现题目要求
    unsigned a, b, c;
    printf("Input unsigned integer numbers a, b, c:\n");
    scanf("%u %u %u", &a, &b, &c);
    printf("%u*%u%%%u=%u\n", a, b, c, mod(a, b, c));
    
        //此部分用于检验答案是否正确
    unsigned long long ab, bb, cb;
    ab = a;
    bb = b;
    cb = c;
    printf("%llu*%llu%%%llu=%llu", ab, bb, cb, ab * bb % cb);
}

遇到的问题

在处理较小的数据时,一切正常。但当处理较大数据时,如2147483647*2147483647/3,就会得到错误的答案。

另外我是根据题目的公式写的代码,不是很清楚具体原理。

  • 写回答

3条回答 默认 最新

  • CSDN专家-link 2021-11-06 14:07
    关注

    unsigned sum = a * ((b >> 30) & 1);
    改为
    unsigned long long sum = a * ((b >> 30) & 1);

    否则表达式中的 sum << 1 会溢出的

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • 关注

    2147483647*2147483647的结果越界了,把代码中的unsigned 类型的变量都 改成unsigned long long 类型

    评论
  • orange4reg 2021-11-06 14:09
    关注

    看你题目不是说用位运算来实现取模吗?为什么还有用%的?

    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 11月14日
  • 已采纳回答 11月6日
  • 修改了问题 11月6日
  • 修改了问题 11月6日
  • 展开全部

悬赏问题

  • ¥30 宾馆客房管理系统可视化
  • ¥20 unity打光没有照亮物体
  • ¥25 powershell如何拷贝1周前的文件
  • ¥15 询问MYSQL查询SQLSERVER数据表并比较差异后,更新MYSQL的数据表
  • ¥15 关于#前端#的问题,请各位专家解答!
  • ¥15 最小生成树问题 Prim算法和Kruskal算法
  • ¥25 医院住院病人呼叫器设计
  • ¥15 不想和现在的团队合作了,怎么避免他们对程序动手脚
  • ¥20 C语言字符串不区分大小写字典排序相关问题
  • ¥15 关于#python#的问题:我希望通过逆向技术爬取1688搜索页下滑加载的数据