1 条题解
-
0
思路
题意:读入整数 ,输出它的 8 位二进制补码。
核心观察
固定位宽下的补码,与“先对 取模、再按无符号二进制展开”完全等价:
- 当 时,,二进制展开就是原码,也就是补码。
- 当 时,,最高位为 1,恰好等于“符号位不变、其余位取反再加 1”的结果。
例如 ,与按定义求出的补码一致。
这样就不必分别处理正负两种情形,也不需要真的做取反加一。
实现步骤
- 由位宽算出掩码
mask = 2^bits - 1; - 令
val = n & mask,得到该位宽下的无符号值(负数在此步被转换成补码形式); - 从第
bits-1位到第 0 位,依次取(val >> i) & 1拼成'0'/'1'字符串; test(n)用默认位宽 8 调用并输出结果。
代码中
minv、maxv只是记录该位宽能表示的数值范围,不参与实际计算。另外bits == 64时1 << 64属于未定义行为,所以掩码分支写成 0 作为占位;本题固定 8 位,不会走到该分支。复杂度
时间 ,空间 ,与 的大小无关。
代码
#include <bits/stdc++.h> using namespace std; // 返回 n 的 bits 位补码(默认 8 位) string two_complement(int n, int bits = 8) { int minv = -(1 << (bits-1)); // 该位宽可表示的最小值(仅作记录,未参与计算) int maxv = (1 << (bits-1)) - 1; // 该位宽可表示的最大值(仅作记录,未参与计算) // 低 bits 位全为 1 的掩码;64 位时 1<<64 未定义,用 0 占位(本题不会触发) int mask = (bits == 64) ? 0 : ((1 << bits) - 1); int val = n & mask; // 取模 2^bits,负数由此变成补码对应的无符号值 string s; for (int i = bits-1; i >= 0; --i) { // 从高位到低位依次取二进制位 s.push_back( (val >> i) & 1 ? '1' : '0' ); } return s; } // 按题目要求输出 n 的 8 位补码 void test(int n){ string s = two_complement(n); cout << s << "\n"; } int main() { int n; cin >> n; test(n); return 0; }
- 1
信息
- ID
- 37
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者