Что такое арифметический underflow и overflow в C?

Что означает арифметический underflow и overflow в программировании на C?

4 ответов


переполнения

от http://en.wikipedia.org/wiki/Arithmetic_overflow:

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

Так, например:

uint32_t x = 1UL << 31;
x *= 2;  // Overflow!

обратите внимание, что, как @ R упоминает в комментарии ниже, стандарт C предлагает:

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

конечно, это довольно своеобразное определение "переполнение". Большинство людей ссылаются на уменьшение по модулю (i.e wrap-around) как "переполнение."

Underflow

от http://en.wikipedia.org/wiki/Arithmetic_underflow:

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

Так, например:

float x = 1e-30;
x /= 1e20; // Underflow!

компьютеры используют только 0 и 1 для представления данных, так что диапазон значений, которые могут быть представлены ограничено. Многие компьютеры используют 32 бита для хранения целых чисел, поэтому самое большое целое число без знака, которое может быть сохранено в этом случае, - 2^32 -1 = 4294967295. Но первый бит используется для представления знака, так что, по сути, наибольшее значение 2^31 - 1 = 2147483647.

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

аналогично, с вещественными числами показатель, который слишком мал для хранения, вызывает недостаточный поток.


int, наиболее распространенный тип данных в C, является 32-разрядным типом данных. Это означает, что каждому int дается 32 бита в памяти. Если бы у меня была переменная

int a = 2;

это фактически будет представлено в памяти как 32-разрядное двоичное число: 000000000000000000000000000000000010.

Если у вас есть два двоичных числа, таких как

10000000000000000000000000000000
и
10000000000000000000000000000000,

их сумма будет 100000000000000000000000000000000, что на 33 бита. Однако компьютер принимает только 32 наименее значимых бита, которые все равны 0. В этом случае компьютер распознает, что сумма больше, чем может храниться в 32 битах, и выдает ошибку переполнения.

underflow-это в основном то же самое, что происходит в противоположном направлении. Стандарт с плавающей запятой, используемый для C, допускает 23 бита после десятичного знака; если число имеет точность за пределами этой точки, оно не будет иметь возможность хранить эти биты. Это приводит к ошибке underflow и / или потере точности.


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