如何实现对于长整数的位运算?

Flammable_ice 2014-04-15 08:23:50
小于int类型的就不要回复了,这里研究的是_int64范围的整数,貌似移位运算只能1<<31 所以不太清楚对长整数怎样实现位运算?
...全文
373 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2014-05-06
  • 打赏
  • 举报
回复
高精度数据可以通过,单精度移位的字内移位,字间搬运,搬运并且邻字移位合并,三种操作组合,再加上一种填充操作实现。 字间搬运,搬运并且邻字移位合,并不会同时用到 一个简单的移位 8字移位,最大8*32 -1 = 255,超过 255,直接全部填0,或者-1,不用计算了 左移为例: A:移位非整字 0,1 合并到4,1,2 合并到5.。。。。 【 搬运并 合并 】 【 填充 】【0 /1 】【1/ 2】【2 /3 】【3 /4 】 【0】【1】【2】【3】【 4】【 5】【 6 】【 7 】 B:移位整字 【 填充 】【 搬运 】 【0】【1】【2】【3】【4】【5】【6 】【7 】 移位以外的,其他位运算比较简单,直接逐字位运算即可。
赵4老师 2014-05-06
  • 打赏
  • 举报
回复
//有一个二进制文件,要求每隔50bits,删除后面的12bits。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fi,*fo;
char buf[31];
char obf[31];
int bn,n;
void filter() {//对buf中前n个字节中的位,每隔50bits,忽略12bits,结果放在obf中,且将bn设置为obf中的字节数。
    char bit[249];
    char obt[249];
    char b8[33];
    char b88[33];
    int i,j;
    char *e;

    for (i=0;i<n;i++) {
        _itoa(buf[i],b8,2);
        sprintf(b88,"%032s",b8);
        sprintf(bit+i*8,"%s",b88+24);
    }

    j=0;
    for (i=0;i<n*8;i++) {
        if (i%62<50) {
            obt[j]=bit[i];
            j++;
        }
    }
    if (j%8) {
        bn=(j/8+1)*8;
    } else {
        bn=j;
    }
    for (i=j;i<bn;i++) obt[i]='0';
    obt[bn]=0;
    bn=bn/8;
    for (i=0;i<bn;i++) {
        strncpy(b8,obt+i*8,8);b8[8]=0;
        obf[i]=(char)strtol(b8,&e,2);
    }
}
int main() {
    fi=fopen("in.bin","rb");
    if (NULL==fi) {
        printf("Can not open file in.bin!\n");
        return 1;
    }
    fo=fopen("out.bin","wb");
    if (NULL==fo) {
        fclose(fi);
        printf("Can not open file out.bin!\n");
        return 2;
    }
    while (1) {
        n=fread(buf,1,31,fi);
        if (0==n) break;
        filter();
        fwrite(obf,1,bn,fo);
    }
    fclose(fo);
    fclose(fi);
    return 0;
}
赵4老师 2014-05-05
  • 打赏
  • 举报
回复
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码!
#include <stdio.h>
unsigned __int64 v;
int i;
int main() {
    for (i=0;i<64;i++) {
        v=1ui64<<i;
        printf("1ui64<<%d==0x%016I64Xui64\n",i,v);
    }
    return 0;
}
//1ui64<<0==0x0000000000000001ui64
//1ui64<<1==0x0000000000000002ui64
//1ui64<<2==0x0000000000000004ui64
//1ui64<<3==0x0000000000000008ui64
//1ui64<<4==0x0000000000000010ui64
//1ui64<<5==0x0000000000000020ui64
//1ui64<<6==0x0000000000000040ui64
//1ui64<<7==0x0000000000000080ui64
//1ui64<<8==0x0000000000000100ui64
//1ui64<<9==0x0000000000000200ui64
//1ui64<<10==0x0000000000000400ui64
//1ui64<<11==0x0000000000000800ui64
//1ui64<<12==0x0000000000001000ui64
//1ui64<<13==0x0000000000002000ui64
//1ui64<<14==0x0000000000004000ui64
//1ui64<<15==0x0000000000008000ui64
//1ui64<<16==0x0000000000010000ui64
//1ui64<<17==0x0000000000020000ui64
//1ui64<<18==0x0000000000040000ui64
//1ui64<<19==0x0000000000080000ui64
//1ui64<<20==0x0000000000100000ui64
//1ui64<<21==0x0000000000200000ui64
//1ui64<<22==0x0000000000400000ui64
//1ui64<<23==0x0000000000800000ui64
//1ui64<<24==0x0000000001000000ui64
//1ui64<<25==0x0000000002000000ui64
//1ui64<<26==0x0000000004000000ui64
//1ui64<<27==0x0000000008000000ui64
//1ui64<<28==0x0000000010000000ui64
//1ui64<<29==0x0000000020000000ui64
//1ui64<<30==0x0000000040000000ui64
//1ui64<<31==0x0000000080000000ui64
//1ui64<<32==0x0000000100000000ui64
//1ui64<<33==0x0000000200000000ui64
//1ui64<<34==0x0000000400000000ui64
//1ui64<<35==0x0000000800000000ui64
//1ui64<<36==0x0000001000000000ui64
//1ui64<<37==0x0000002000000000ui64
//1ui64<<38==0x0000004000000000ui64
//1ui64<<39==0x0000008000000000ui64
//1ui64<<40==0x0000010000000000ui64
//1ui64<<41==0x0000020000000000ui64
//1ui64<<42==0x0000040000000000ui64
//1ui64<<43==0x0000080000000000ui64
//1ui64<<44==0x0000100000000000ui64
//1ui64<<45==0x0000200000000000ui64
//1ui64<<46==0x0000400000000000ui64
//1ui64<<47==0x0000800000000000ui64
//1ui64<<48==0x0001000000000000ui64
//1ui64<<49==0x0002000000000000ui64
//1ui64<<50==0x0004000000000000ui64
//1ui64<<51==0x0008000000000000ui64
//1ui64<<52==0x0010000000000000ui64
//1ui64<<53==0x0020000000000000ui64
//1ui64<<54==0x0040000000000000ui64
//1ui64<<55==0x0080000000000000ui64
//1ui64<<56==0x0100000000000000ui64
//1ui64<<57==0x0200000000000000ui64
//1ui64<<58==0x0400000000000000ui64
//1ui64<<59==0x0800000000000000ui64
//1ui64<<60==0x1000000000000000ui64
//1ui64<<61==0x2000000000000000ui64
//1ui64<<62==0x4000000000000000ui64
//1ui64<<63==0x8000000000000000ui64
//
lm_whales 2014-05-05
  • 打赏
  • 举报
回复
带符号右移结果为符号位, 不带符号右移结果为0
lm_whales 2014-05-05
  • 打赏
  • 举报
回复
只用C,C++语言的位运算,只能在整数类型的位宽下进行。 超长的高精度数据(整数类型数组表示),可以利用单精度数据的位运算,进行 实际上可以实现,任意长度任意位的任何位运算。 注意到,超过一定位宽的移位,根据数学的逻辑,左移结果为0, 右移根据数据表示带符号和不带符号数有所不同, 带符号右移结果为0, 不带符号右移结果为0是符号位 所以,高精度数据位运算,比C,C++语言的位运算,更加明确(不用考虑硬件平台,,因为比他位数多很多), 实现起来也很容易。 不像C,C++语言的位运算,还搞个未定义。自己实现的完全没有这个必要。
Flammable_ice 2014-05-05
  • 打赏
  • 举报
回复
总结楼上几位的结论是:移位操作符只能在编译器内置类型范围内实现?
赵4老师 2014-04-17
  • 打赏
  • 举报
回复
引用 10 楼 z84616995z 的回复:
[quote=引用 8 楼 zhao4zhong1 的回复:] 1i64<<40
没看懂。1i64是啥意思?以及你下面一大段英文要表达什么?[/quote] 英语也是一门计算机语言的说。
Flammable_ice 2014-04-17
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
1i64<<40
没看懂。1i64是啥意思?以及你下面一大段英文要表达什么?
赵4老师 2014-04-16
  • 打赏
  • 举报
回复
常量也有类型! C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types. Syntax integer-constant : decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence' decimal-constant : nonzero-digit decimal-constant digit octal-constant : 0 octal-constant octal-digit hexadecimal-constant : 0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit nonzero-digit : one of 1 2 3 4 5 6 7 8 9 octal-digit : one of 0 1 2 3 4 5 6 7 hexadecimal-digit : one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F integer-suffix : unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt unsigned-suffix : one of u U long-suffix : one of l L 64-bit integer-suffix : i64 To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type. To specify a decimal constant, begin the specification with a nonzero digit. For example: int i = 157; // Decimal constant int j = 0198; // Not a decimal number; erroneous octal constant int k = 0365; // Leading zero specifies octal constant, not decimal To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example: int i = 0377; // Octal constant int j = 0397; // Error: 9 is not an octal digit To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example: int i = 0x3fff; // Hexadecimal constant int j = 0X3FFF; // Equal to i To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example: unsigned uVal = 328u; // Unsigned value long lVal = 0x7FFFFFL; // Long value specified // as hex constant unsigned long ulVal = 0776745ul; // Unsigned long value
赵4老师 2014-04-16
  • 打赏
  • 举报
回复
1i64<<40
lm_whales 2014-04-16
  • 打赏
  • 举报
回复
用32Bits移位实现 n*32Bits 移位也不是很复杂的事情,不必太纠结 32Bits 和 64Bits一起, 实现128Bits,256Bits ,32Bits* N , 移位都是很简单的事情 一般来说 N *32 Bits 除法,开方等等运算比较麻烦一点 只用32Bits,加减乘除实现32Bits*N 加减乘除,比较麻烦一点。 加减乘,需要处理溢出; 乘法如果N比较大,需要减小时间复杂度,提高程序运行的速度; 除法实现起来,本来就比较麻烦一点。
turing-complete 2014-04-15
  • 打赏
  • 举报
回复
如果您的编译器支持128位的整数,那么就有这样的运算。 说句题外话,如果编译器支持这么长的整型,那么也不存在什么“长整数”的运算问题了,因为编译器就内置支持了。
Flammable_ice 2014-04-15
  • 打赏
  • 举报
回复
引用 4 楼 mougaidong 的回复:
这能说明什么? 说明的你用的是一个32位的有符号整型而已。 [quote=引用 3 楼 z84616995z 的回复:] [quote=引用 2 楼 mougaidong 的回复:] “移位运算只能1<<31 ”?
[/quote][/quote] 大神!你说对了! 我又试了一下,可以达到64位,那么有没有可能达到更高位数的位运算?比如128位?我想用位运算实现长整数的除法,并且需要使用"<<,>>,^,& |,~" 其中某几个符号,给个提示就好!
turing-complete 2014-04-15
  • 打赏
  • 举报
回复
这能说明什么? 说明的你用的是一个32位的有符号整型而已。
引用 3 楼 z84616995z 的回复:
[quote=引用 2 楼 mougaidong 的回复:] “移位运算只能1<<31 ”?
[/quote]
Flammable_ice 2014-04-15
  • 打赏
  • 举报
回复
引用 2 楼 mougaidong 的回复:
“移位运算只能1<<31 ”?
turing-complete 2014-04-15
  • 打赏
  • 举报
回复
“移位运算只能1<<31 ”?
gdreamlend 2014-04-15
  • 打赏
  • 举报
回复
用string进行存储,然后从后往前按位进行计算

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧