Win32API中intsafe.h整数无符号绝对值实现的疑问
关于C/C++中无符号绝对值实现的疑问
问题背景
我不熟悉C/C++,但知晓以下代码用于获取整数的无符号绝对值。疑惑微软开发者为何要采用先给整数加1、取负后再加1的实现方式,而非直接转换为无符号整数?
//intsafe.h if (llMultiplicand < 0) { // // Avoid negating the most negative number. // ullMultiplicand = ((ULONGLONG)(- (llMultiplicand + 1))) + 1; } else { ullMultiplicand = (ULONGLONG)llMultiplicand; }
例如,对于4位整数,其最小值为-8,二进制表示为1000。我知道对它取负后结果仍是1000,但此时直接转换为无符号整数就能得到其无符号绝对值。我曾猜测是性能问题,但多次用C语言测试后难以看出差异,还发现函数在代码中的位置会影响整体耗时(如先声明实现abs1还是abs2函数),调用位置相同但结果不同,对此无法理解。
测试代码
unsigned int abs1(int x) { if (x < 0) { return (unsigned int)(-x); } return (unsigned int)x; } unsigned int abs2(int x) { if (x < 0) { return (unsigned int)(-(x + 1) + 1); } return (unsigned int)x; } int main() { int numIterations = 100000000; clock_t start, end; double cpu_time_used; // Test abs1 start = clock(); for (int i = 0; i < numIterations; i++) { abs1(-5); // Replace -5 with your test input } end = clock(); cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; printf("Time taken by abs1: %f seconds\n", cpu_time_used); // Test abs2 start = clock(); for (int i = 0; i < numIterations; i++) { abs2(-5); // Replace -5 with your test input } end = clock(); cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; printf("Time taken by abs2: %f seconds\n", cpu_time_used); return 0; }
最终理解
后续我理解到根本原因是C/C++标准中存在诸多未定义行为,标准化库不应触发这类行为(即便部分实现有特定表现),且编译器优化会让未定义行为变得不可预测,这与官方主导实现的新型语言不同。
内容的提问来源于stack exchange,提问作者rwxe
相关产品推荐
相关产品推荐

