EgoRusMarch
@EgoRusMarch
C++ Developer

Как избавиться от переполнения?

Написал вот такую прогу для вывода ряда Фибоначи (0,1,1,2,3,5,8,13,21,34,55,89...):
#include <stdio.h>

void main(void) {
	double a, b;
	int n;

	a = 0;
	b = 1;

	system("TITLE fibonachi");
	system("COLOR F1");
	printf("Введите количество итераций (не меннее двух):\t");
	scanf("%d", &n); 
	printf("\n%.0f\n%.0f\n", a, b);

	n -= 2;
	while(n > 0) {
		a += b;
		printf("%.0f\n", a);
		n--;
		if(n > 0) {
			 b += a;
			 printf("%.0f\n", b);
			 n--;
		}
	}

	system("PAUSE");
}

Вот что получилось:
3345c4fbb3d841819f6a784a6e407a6e.png
Если заменить на unsigned int и выводить как %u, то вот что получается:
4fffc73455824674916fe67519740006.png
Хотя где-то читал, что переполнения беззнаковых целых быть не должно.
  • Вопрос задан
  • 586 просмотров
Решения вопроса 4
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
где-то читал, что переполнения беззнаковых целых быть не должно.

Нет никакой магии в беззнаковых целых, максимальное представимое число -- 2^(количество бит)-1, от больших чисел остаётся остаток по модулю 2^(количество бит). Это поведение описано стандартами языка C.
Ответ написан
Комментировать
AtomKrieg
@AtomKrieg
Давай я поищу в Google за тебя
Использовать специальные библиотеки для больших чисел. А в вашей программе никак не избавиться.
Вычисления делаются через Double, у него есть ограничение на точность по мантиссе. Потом переводите в uint - все что в мантиссу не влезло превратилось в нули.
Ответ написан
Комментировать
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Что значит "переполнения беззнаковых целых быть не должно"?
То есть, объявив переменную как unsigned int я сразу получу возможность считать любую разрядность?
Конечно же переполнение есть, uint32 может содержать значения [0..4'294'967'295], uint64 - [0..18'446'744'073'709'551'615]. Хотите больше - используйте или пишите сами реализацию длинной арифметики.
Ответ написан
Механизм переполнения отличается в signed и unsigned типах.
  1. Пусть имеется переменная signed int num = INT_MAX; Тогда при ++num; что окажется в num -- unspecified. То есть может оказаться INT_MIN, а может 42.
  2. Пусть имеется переменная unsigned int num = UINT_MAX; Тогда при ++num; в num обязано оказаться 0, в соответствии со стандартом.

Я так понял, что ваш источник под этим:

переполнения беззнаковых целых быть не должно

Имел в виду, что unsigned типы при переполнении безболезненно возвращаются (wrap) в 0, в отличие от signed.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы