我正在研究K&R第二版,并且无法弄清楚为什么我会得到一定的结果.我正在解决的问题是计算数据类型的上限和下限.特别:
"编写一个程序来确定char,short,int和long变量的范围,包括有符号和无符号,通过从标准头文件中打印适当的值并直接计算.如果你计算它们会更难:确定各种浮动的范围 - 点类型."
我已经了解了按位运算符和两个人的称赞,并且我认为应该对签名数据类型有效,但是它适用于对我没有任何意义的无符号数据类型.这是代码:
#include <stdio.h>
main()
{
signed int i;
i = ~0;
i >>= 1;
printf("Upper limit: %d\n", i);
printf("Lower limit: %d\n", -i -1);
}
Run Code Online (Sandbox Code Playgroud)
这将导致-1被打印为上限,0被打印为下限.但是,如果我将i更改为unsigned int,我会得到我期望的结果(2147483647和-2147483648).我无法解决这个问题,因为我的理解是unsigned int永远不会小于0,而signed int应该使用这些按位运算符,即如果它是32位系统,
~0 == 11111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)
,和
~0 >> 1 == 011111111111111111111111111111111,
or 2147483647.
Run Code Online (Sandbox Code Playgroud)
知道我哪里错了吗?
我们正在编写一个模拟器,我们需要在该模拟器中传播右移信号。仿真系统使用2的补码。
我读到>>C中有符号整数的运算符是实现定义的。因此,我不能依靠它会在所有平台上产生正确位模式的事实。
这意味着我将需要使用位操作来重现算术右移,并且我将尽可能避免不必要的分支。
编辑:
回应评论:
“缺少的位是当在x >> y中的x中设置符号位时,OP需要定义什么结果是“正确的””
我基本上想重现SAR x86指令的行为。负数用2的补码表示。右移基本上也应意味着除以2即可得到负数。
这意味着对于以1开头的位模式。因此,对于1xxxxxxx,向右移位应为11xxxxxx。对于以0开头的位模式,因此0xxxxxxx右移应为00xxxxxx。因此,MSB是“粘性”的。没有定义超过字长的移位。
我看到
#define NUM_MAX_VOLUME 0ui64
Run Code Online (Sandbox Code Playgroud)
在别人的代码中
0ui64 是多少号?但它似乎不是一个十六进制数字。
unsigned int a=200;
//mov dword ptr [a],0C8h
a >>= 1;
//mov eax,dword ptr [a]
//shr eax,1
//mov dword ptr [a],eax
a /= 2;
//mov eax,dword ptr [a]
//shr eax,1
//mov dword ptr [a],eax
int b = -200;
//mov dword ptr [b],0FFFFFF38h
b /= 2;
//mov eax,dword ptr [b]
//cdq
//sub eax,edx
//sar eax,1
//mov dword ptr [b],eax
b >>= 1;
//mov eax,dword ptr [b]
//sar eax,1
//mov dword ptr [b],eax
Run Code Online (Sandbox Code Playgroud)
我正在使用 msvc,// 是该 C 语句的程序集。
为什么signed int/=2不同于>>=1 …
对于使用位掩码的程序我渴望以二进制写数字...即要复制的第8位x到z,我写的
y = 0xff000000;
z = 0;
z = (y & x) | z
Run Code Online (Sandbox Code Playgroud)
哪里x, y, z都有int.现在使用左移和右移运算符我想y向右或向左移动1s 来掩码另一组位,所以我写下面的代码
cout<< bitset<32>(y>>10) <<"\n" << bitset<32>(y<<10) <<endl;
Run Code Online (Sandbox Code Playgroud)
现在我的预期输出是:
00000000001111111100000000000000
00000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
但我得到了:
11111111111111111100000000000000
00000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
我有一个位掩码(存储为短).出于各种目的,我想将除最后5位之外的所有内容归零 - 我确信通过按位运算符可以很容易地实现这一点,但它让我望而却步.
1010 01101 1011 0111 -> 0000 0000 0001 0111
Run Code Online (Sandbox Code Playgroud)
谢谢
为什么这段代码会进入无限循环?
虽然它可以在其他机器上工作.机器也是'小端.它将继续打印-1值;
void printfbit(int n)
{
while (n) {
if (n & 1)
printf("1");
else
printf("0");
n = n >> 1;
printf("\t %d\n",n);
}
//printf("\n");
}
Run Code Online (Sandbox Code Playgroud) 我有以下程序:
int main()
{
int64_t a = 241294423792285589;
printf("a = %lld, a << 63 = %lld", a, a << 63);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我原本希望a << 63是0,但它会打印出来:
a = 241294423792285589, a << 63 = -9223372036854775808
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
我一直在看这段代码一小时......我拼命想找到错误.
#include <iostream>
int main()
{
for (int32_t n = 1; n>= 0; n--)
{
std::cout << "n: " << n << std::endl;
std::cout << std::dec << " 64 - n: " << (64 - n) << std::endl;
std::cout << std::hex << " 0x1ULL << 64: " << (0x1ULL << 64) << std::endl;
std::cout << std::hex << " 0x1ULL << (64 - n): " << (0x1ULL << (64 - n)) << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
那是输出:
n: 1
64 - n: …Run Code Online (Sandbox Code Playgroud) 例如,我有两位数字:
0b0111111
0b0000110
Run Code Online (Sandbox Code Playgroud)
我想将状态变量移位7位并将它们组合在一起.
0b00001100111111
Run Code Online (Sandbox Code Playgroud)
我可以通过转移完成吗?