Целочисленное переполнение (наименьший размер файла, из-за которого целое число в программе становится отрицательным в битах) - PullRequest
1 голос
/ 02 июля 2019

Я написал цифровой калькулятор на Сиas char затем сохраняет его в целом числе и продолжает добавлять использование к целому числу до тех пор, пока не достигнет EOF.Программа работает отлично.

FILE *fp;
char inpfile[20];
char c;
int sumdigsig = 0;

// reading in the name of the file using inpfile
printf("Please Enter name of the File:\n");
scanf("%s",inpfile);
// checking if the file exisits
if((fp = fopen(inpfile,"r")) == NULL){
        fprintf(stderr,"File does no Exsist\n");
        exit(1);
}
// If the file exsists using fgetc to read in until endoffile is reached
// and casting char to int and suming it 
  c = fgetc(fp);
while(c != EOF){
        sumdigsig += (int)c;
        c = fgetc(fp);
}
printf("%d\n",sumdigsig);

}

Программа отлично работает, это просто справка, чтобы вы знали, что происходит.запуск действительно большого файла приводит к отрицательному числу, как и ожидалось, но мне нужно знать, какой размер файла в битах приведет к переполнению целого числа и получению отрицательного значения.

Ответы [ 2 ]

2 голосов
/ 03 июля 2019

Мне нужно знать, какой размер файла в битах приведет к переполнению целого числа и получению отрицательного значения.

(Вы имеете в виду «размер файла в байт »Файлы редко измеряются в битах.

То, как вы это делаете, зависит от байтов в файле.Как только сумма байтов, которые вы добавляете вместе, превышает INT_MAX (см. limits.h), значение совокупной суммы int преобразуется в отрицательное значение.

Таким образом, максимальное значениеколичество байтов для конкретного файла будет на одно число меньше, чем число байтов, из-за которых суммация превысила INT_MAX.т. е. на единицу меньше, чем число байтов, которые вы прочитали из файла, в точке, где сумма сначала превышает INT_MAX - или, с практической точки зрения обнаружения этого в коде, сначала становится отрицательным.

ИКак указывает один из комментариев, если все байты равны 0x00, то даже бесконечно большой файл никогда не будет соответствовать этому критерию.

РЕДАКТИРОВАТЬ 1: Что касается комментарияо том, что поведение переполнения не определено, вместо определения, стала ли сумма отрицательной, вместо этого проверьте, меньше ли (INT_MAX - sum) значения последнего прочитанного байта, до , добавляя значение этого байта к сумме.

РЕДАКТИРОВАТЬ 2: Выражено в коде:

основной цикл, как я бы переписал его

c = 0;
bytes = 0;
while (1) {
    if ((c = fgetc(fp)) == EOF) break;

    if ((INT_MAX - sumdigsig) >= c) {
        sumdigsig += c;
        bytes++;
    } else {
        break;
    }
}

пробных прогонов

head -c 1073741824 < /dev/urandom > large-file-of-random-bytes

./sum-file-bytes
Please Enter name of the File : large-file-of-random-bytes
sum is : 2147483572; read 16845621 bytes to reach that sum

head -c 1073741824 < /dev/zero > large-file-of-zeros

./sum-file-bytes
Please Enter name of the File : large-file-of-zeros
sum is : 0; read 1073741824 bytes to reach that sum
0 голосов
/ 02 июля 2019

В 64-битной и 32-битной машинах диапазон значений целых чисел со знаком равен -2,147,483,648 to 2,147,483,647

Так что, если «sumdigsig» пересекает «(положительное) максимальное значение», то оно будет идтиназад к отрицательному диапазону.

Давайте рассмотрим небольшой пример: Рассмотрим, находится ли диапазон от -10 до +9

   --->   -10 -9 -8 -7 -6 -5 -4 -3 -2 -1  ----
  |                                           |
   ---    +9 +8 +7 +6 +5 +4 +3 +2 +1  0   <---

, рассмотрим a = 4. Итакесли вы сделаете a = a + 6, то есть тогда станет -10, потому что он превышает диапазон.

Таким же образом для целого числа, если значение пересекло максимальное значение, тогда оно вернется к отрицательному значению.диапазон.

Пруф:

#include <stdio.h>

int main()
{
    // a contains the maxium value
    int a = 2,147,483,647;
    a = a + 1; 
    printf("%d", a);
    return 0;
}

Выход

-2,147,483,648

Предложение: Вместоиспользования signed-integer с unsigned Integer.Вы можете получить большой диапазон, т.е. 2,147,483,647 + 2,147,483,648

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...