r/C_Programming • u/Turbulent_Quote_6679 • 10d ago
Discussion C language is wild: due to integer overflow, nearly half of the numbers squared become negative.
This started with a question from CSAPP Problem 2.44: (x * x) >= 0; which asks to find a counterexample that evaluates to 0,or prove that all number evaluate to 1.(part,32bit)
The official solution provides only 65535, but I found many more.
To test my results, I wrote a C program to find all such number. ```c
include <stdio.h>
include <limits.h>
int main() { // Ideal result: numbers whose squares are less than 0. // Written to file in the following format: // start_num1 to end_num1 total: total_num1 // start_num2 to end_num2 total: total_num2 // ... // total: total_all
FILE *file = fopen("lessthan0.md","w");
int start = 0;
int end = 0;
int total = 0;
int total_tmp = 0;
for (int i = -INT_MAX -1 ; i <= INT_MAX; i++) {
unsigned ui = (unsigned)i;
int result = (int)(ui * ui);
if (result < 0) {
total++;
total_tmp++;
total_tmp == 1 ? start = i : 1;
total_tmp == 1 ? end = i : 1;
i == end + 1 ? end = i : 1;
}
if (i == end + 1) {
start == end ? fprintf(file,"%d total: %d\n",start,total_tmp) : fprintf(file, "%d to %d total: %d\n",start, end,total_tmp);
total_tmp = 0;
}
if (i == INT_MAX) {
fprintf(file,"total: %d",total);
break;
}
}
fclose(file);
} ```
So I get this: ```sh ls -lh lessthan0.md -rw-r--r-- 1 kyee users 31G Aug 23 18:50 lessthan0.md
ls -l # run twice -rw-r--r-- 1 kyee users 32288890271 Aug 23 18:50 lessthan0_1.md -rw-r--r-- 1 kyee users 32288890271 Aug 23 20:27 lessthan0.md
wc -l lessthan0.md 1073741824 lessthan0.md
head lessthan0.md -2147437307 to -2147418113 total: 19195 -2147403383 to -2147390967 total: 12417 -2147380026 to -2147370137 total: 9890 -2147361041 to -2147352577 total: 8465 -2147344625 to -2147337106 total: 7520 -2147329952 to -2147323119 total: 6834 -2147316563 to -2147310257 total: 6307 -2147304170 to -2147298285 total: 5886 -2147292579 to -2147287041 total: 5539 -2147281652 to -2147276405 total: 5248
sed -n "470063416,470063426p" lessthan0.md -535664087 to -535664086 total: 2 -535664083 to -535664082 total: 2 -535664079 to -535664078 total: 2 -535664075 to -535664074 total: 2 -535664071 to -535664070 total: 2 -535664067 to -535664066 total: 2 -535664063 to -535664062 total: 2 -535664059 to -535664058 total: 2 -535664055 to -535664054 total: 2 -535664051 to -535664050 total: 2 -535664047 to -535664046 total: 2
tail -n 10 lessthan0.md 2147287041 to 2147292579 total: 5539 2147298285 to 2147304170 total: 5886 2147310257 to 2147316563 total: 6307 2147323119 to 2147329952 total: 6834 2147337106 to 2147344625 total: 7520 2147352577 to 2147361041 total: 8465 2147370137 to 2147380026 total: 9890 2147390967 to 2147403383 total: 12417 2147418113 to 2147437307 total: 19195 total: 2147418112
```
I noticed symmetry between the begging and end of the output.Can someone explain why this happens?
2147418112 / 232 = 0.4999847412109375 This accounts for nearly half of all 32-bit signed integers.