c - 意外导致 C 的长整数除法
问题描述
我尝试在 C 中进行长整数除法,但我无法得到正确的结果。我很好奇我遇到崩溃的原因以及如何获得正确的结果。
#include <stdio.h>
#include <stdint.h>
int main() {
int64_t a = 0x8000000000000000;
int64_t b = 0xffffffffffffffff;
printf("a: %ld; b: %ld\n", a, b);
int64_t c = a/b;
printf("a/b: %ld\n", c);
return 0;
}
结果如下:
(base) ➜ ~ gcc test.c -O2
(base) ➜ ~ ./a.out
a: -9223372036854775808; b: -1
a/b = : -9223372036854775808
(base) ➜ ~ gcc test.c
(base) ➜ ~ ./a.out
a: -9223372036854775808; b: -1
[1] 39193 floating point exception (core dumped) ./a.out
解决方案
正如您已经注意到的,打印a
和b
:
int64_t a = 0x8000000000000000;
int64_t b = 0xffffffffffffffff;
printf("a:%" PRId64 ", b:%" PRId64 "\n", a, b);
产生以下结果:
a:-9223372036854775808, b:-1
但是,在 64 位机器上除以 64 位有符号整数是一种INT64_MIN
未定义的行为。-1
二进制补码算术的一个可怕的伪影是“最负数”问题。拿这个代码:
int8_t a = -127; //-127 to 127 OK
int8_t b = -1;
printf("a/b: %hhd\n", a/b);
此代码适用于除( )a
之外的任何值。那是因为:-128
INT8_MIN
1000 0000 (-128)
0111 1111 (bit flip)
1000 0000 (add one, back at -128!!)
但实际上,如果您查看最后一步:
0111 1111 (bit flip)
如果你加一个,我们已经溢出了,因为第一位被保留为符号位。
推荐阅读
- javascript - 在 Web Speech API 中跟踪本地语音的开始
- javascript - 重新加载电子浏览器时html元素被打乱
- python - Python-删除重复行 Pandas(具体)
- ios - 将搜索栏和位置按钮添加到 MapKit 视图控制器
- javascript - React - axios.post 错误“请求失败,状态码 404”
- .net-core - 使用 Azure Active Directory 的 Azure SQL 身份验证
- java - IllegalStateException: TimeSkipEvent 只能同步触发
- wpf - 如何以编程方式使用 vb.net 更改 WPF 中数据网格列的字符串格式?
- javascript - 直接链接到位于 Google Drive 上的文件
- timer - 为什么这个 PLC TON 没有在 Studio 5000 v32.11 中激活