惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
S
Schneier on Security
P
Palo Alto Networks Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Securelist
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
AI
AI
C
CERT Recently Published Vulnerability Notes
C
Cyber Attacks, Cyber Crime and Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
TaoSecurity Blog
TaoSecurity Blog
O
OpenAI News
Cyberwarzone
Cyberwarzone
G
GRAHAM CLULEY
SecWiki News
SecWiki News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cisco Blogs
K
Kaspersky official blog
Spread Privacy
Spread Privacy
S
Security @ Cisco Blogs
Hacker News - Newest:
Hacker News - Newest: "LLM"
IT之家
IT之家
有赞技术团队
有赞技术团队
B
Blog
T
Tailwind CSS Blog
PCI Perspectives
PCI Perspectives
P
Privacy & Cybersecurity Law Blog
Last Week in AI
Last Week in AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Webroot Blog
Webroot Blog
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hacker News: Front Page
The Cloudflare Blog
C
Cybersecurity and Infrastructure Security Agency CISA
美团技术团队
V
V2EX
腾讯CDC
S
SegmentFault 最新的问题
Security Archives - TechRepublic
Security Archives - TechRepublic

Keyle's Blog

公司搬家 | Keyle's Blog 听闻的一些故事 | Keyle's Blog 《恶魔轮盘改》项目完整实现详解:架构、流程与双端同步 | Keyle's Blog .net core服务发布经验总结 | Keyle's Blog 凌晨一点的键盘声 | Keyle's Blog 南京游记 | Keyle's Blog 从老活到小 | Keyle's Blog 一代人有一代人的龙虾要养 | Keyle's Blog 在咖啡凉透前救回了博客数据 | Keyle's Blog 时间的参照物 | Keyle's Blog 沈阳游记 | Keyle's Blog 近况二三则 | Keyle's Blog 阳澄湖游记 | Keyle's Blog 欢乐谷游记 | Keyle's Blog 殊途同归的“搜打撤” | Keyle's Blog 中班学习规划 | Keyle's Blog 桐庐三日游 | Keyle's Blog 9月15日起,租房新规正式实施!居住安全、费用明细、租金调整与权益保障全面解读 | Keyle's Blog 游泳与羽毛球 | Keyle's Blog 8月生活碎片 | Keyle's Blog 卡坦岛桌游玩法 | Keyle's Blog 当时间戳“捣乱”时,互联网会发生什么? | Keyle's Blog 该如何去度过一生 | Keyle's Blog 在Lua中循环Require是如何处理的? | Keyle's Blog
补码陷阱 | Keyle's Blog
2025-10-22 · via Keyle's Blog

为什么这个Bug如此狡猾?

直觉背叛:我们直觉上认为 -A 就是 “负的A”,但在位运算中它变成了”A的补码”
测试遗漏:我们测试了正数情况,但对负数的测试不够充分
认知偏差:我们都”知道”补码,但真正用到时却忘了它的存在

你发现下面代码中的问题了吗 ?

1
2
3
4
5
6
7
8
9

bool ShouldSelect(int value, int mask)
{
if (-value & mask == Mathf.Abs(-value))
{
return -value > 0;
}
return false;
}

在C#中,A & B-A & B 的区别主要在于对负数处理的不同。让我通过具体案例来说明:

案例演示

1
2
3
4
5
6
7
8
9
10
int A = 5;    
int B = 3;


int result1 = A & B;
Console.WriteLine($"A & B = {result1}");


int result2 = -A & B;
Console.WriteLine($"-A & B = {result2}");

二进制分析:

1
2
3
4
5
6
7
A = 5:  0000 0101
B = 3: 0000 0011
A & B: 0000 0001 = 1

-A = -5: 1111 1011 (补码表示)
B = 3: 0000 0011
-A & B: 0000 0011 = 3

更多案例

1
2
3
4
5
6
7
8
9
10
11
12

int A2 = 10;
int B2 = 6;

Console.WriteLine($"{A2} & {B2} = {A2 & B2}");
Console.WriteLine($"-{A2} & {B2} = {-A2 & B2}");


int A3 = -3;
int B3 = -5;

Console.WriteLine($"{A3} & {B3} = {A3 & B3}");

背后的意义

1. 补码表示法

  • 在C#中,整数使用二进制补码表示
  • 正数的补码是其本身
  • 负数的补码 = 对应正数的二进制取反 + 1

2. 运算本质

  • A & B:对两个数的实际二进制位进行按位与
  • -A & B:先计算A的补码(得到-A),再与B进行按位与

3. 实际应用场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

[Flags]
enum Permissions
{
Read = 1,
Write = 2,
Execute = 4
}


Permissions userPermissions = Permissions.Read | Permissions.Write;


bool canRead = (userPermissions & Permissions.Read) != 0;


bool wrongCheck = (-(int)userPermissions & (int)Permissions.Read) != 0;

4. 重要注意事项

1
2
3
4

int A = 5, B = 3;
Console.WriteLine($"-A & B = {-A & B}");
Console.WriteLine($"-(A & B) = {-(A & B)}");

总结

  • A & B 是直接的按位与运算,结果可预测
  • -A & B 涉及补码转换,结果取决于负数的二进制表示
  • 在实际编程中,应避免对负数进行无意义的位运算,除非明确理解补码机制
  • 位运算通常用于标志位、掩码操作等场景,应保持操作数的明确性和可读性

本文标题:补码陷阱

文章作者:Keyle

发布时间:2025-10-22

最后更新:2025-10-22

原始链接:https://vrast.cn/posts/55376/

版权声明:©Keyle's Blog. 本站采用署名-非商业性使用-相同方式共享 4.0 国际进行许可