Что означают арифметические недополнения и переполнения в программировании на C?
Что такое арифметическое недополнение и переполнение в C?
Ответы (4)
Переполнение
Из http://en.wikipedia.org/wiki/Arithmetic_overflow:
состояние, возникающее, когда вычисление дает результат, который по величине больше, чем тот, который может хранить или представлять данный регистр или место хранения.
Так, например:
uint32_t x = 1UL << 31;
x *= 2; // Overflow!
Обратите внимание, что, как упоминает @R в комментарии ниже, стандарт C предлагает:
Вычисление, включающее операнды без знака, никогда не может переполниться, потому что результат, который не может быть представлен результирующим целочисленным типом без знака, уменьшается по модулю числа, которое на единицу больше, чем наибольшее значение, которое может быть представлено результирующим типом.
Конечно, это довольно своеобразное определение «переполнения». Большинство людей назвали бы сокращение по модулю (т. е. циклический переход) «переполнением».
Недополнение
Из http://en.wikipedia.org/wiki/Arithmetic_underflow:
условие в компьютерной программе, которое может возникнуть, когда истинный результат операции с плавающей запятой меньше по величине (то есть ближе к нулю), чем наименьшее значение, представленное как обычное число с плавающей запятой в целевом типе данных.
Так, например:
float x = 1e-30;
x /= 1e20; // Underflow!
unsigned char x = 0; x -= 1;
? считается ли это недостатком?
- person Gamal Othman; 25.02.2019
Компьютеры используют только 0 и 1 для представления данных, поэтому диапазон значений, которые могут быть представлены, ограничен. Многие компьютеры используют 32 бита для хранения целых чисел, поэтому наибольшее целое число без знака, которое можно сохранить в этом случае, равно 2^32 -1 = 4294967295. Но первый бит используется для представления знака, так что на самом деле наибольшее значение равно 2^31 - 1 = 2147483647.
Ситуация, когда целое число вне допустимого диапазона требует больше битов, чем может быть сохранено, называется переполнением.
Точно так же с действительными числами экспонента, которая слишком мала для сохранения, вызывает потерю значимости.
int, самый распространенный тип данных в C, является 32-битным типом данных. Это означает, что каждому int отводится 32 бита в памяти. Если бы у меня была переменная
int a = 2;
это фактически будет представлено в памяти как 32-битное двоичное число: 0000000000000000000000000000000010.
Если у вас есть два двоичных числа, например
100000000000000000000000000000000
и
100000000000000000000000000000000,
их сумма будет 1000000000000000000000000000000000, что составляет 33 бита. Однако компьютер берет только 32 младших значащих бита, все из которых равны 0. В этом случае компьютер распознает, что сумма больше, чем может быть сохранено в 32 битах, и выдает ошибку переполнения.
Нижний поток — это в основном то же самое, происходящее в противоположном направлении. Стандарт с плавающей запятой, используемый для C, допускает 23 бита после запятой; если число имеет точность выше этой точки, оно не сможет сохранить эти биты. Это приводит к ошибке потери значимости и/или потере точности.
int
не является 32-битным типом данных.
- person Philip; 16.06.2011
недозаполнение зависит исключительно от данного алгоритма и заданных входных данных, и, следовательно, программист не может напрямую контролировать его. С другой стороны, переполнение зависит от произвольного выбора программистом объема памяти, зарезервированного для каждого стека, и этот выбор влияет на количество раз, когда может произойти переполнение