Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.10.2015, 05:59   #1
Andrej_K
Форумчанин
 
Регистрация: 27.07.2013
Сообщений: 256
По умолчанию Что происходит в памяти?

Есть код на Си:

Код:
#include <stdio.h>

main (void)
{
	int i = 2;
	int k = 1;

	/* while (k > 0)
	{
		printf ("%d\n", i);
		i *= 2;
	} */
	
	while (k < 33)
	{
		printf ("%d\n", i);
		i *= 2;
		k++;
	}
		
	return 0;
}
1. Почему i становится в какой-то момент отрицательным, а потом и вовсе равным 0? Хочу понять механизм процессов в памяти.

2. Как устроить бесконечное вычисление с огромными числами?
Andrej_K вне форума Ответить с цитированием
Старый 30.10.2015, 06:36   #2
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Сообщение от Andrej_K Посмотреть сообщение
Есть код на Си:

1. Почему i становится в какой-то момент отрицательным, а потом и вовсе равным 0? Хочу понять механизм процессов в памяти.

2. Как устроить бесконечное вычисление с огромными числами?
1. Потому, что используется тип int. 2^33 даст нам 8 589 934 592, а int работает в диапазоне от -32767 до +32768. Улавливаете закономерность?
2. Копайте в сторону "длинная арифметика". Самое большое положительное число в С++, вы можете получить используя тип unsigned long. Если нужны ещё более длинные числа, тут придётся попотеть.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 30.10.2015, 06:47   #3
Andrej_K
Форумчанин
 
Регистрация: 27.07.2013
Сообщений: 256
По умолчанию

Но, если int от -32767 до +32768, то почему тогда такие результаты?
Изображения
Тип файла: jpg Untitled-1.jpg (99.4 Кб, 152 просмотров)
Andrej_K вне форума Ответить с цитированием
Старый 30.10.2015, 07:14   #4
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Сообщение от Andrej_K Посмотреть сообщение
Но, если int от -32767 до +32768, то почему тогда такие результаты?
Ясно. У Вас int четырёхбайтный т.е. 32 разряда. Под конец вычислений, происходит переполнение положительной разрядной сетки. В старший разряд, заносится единица, что расценивается как отрицательный знак. Следующая итерация возведения в степень, начинает счёт с начала, т.е. с нуля.
Проставьте unsigned int, отрицательные числа исчезнут, но переход к нулю останется. Правда не на 33-й, а на 65-й итерации.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder

Последний раз редактировалось Smitt&Wesson; 30.10.2015 в 07:18.
Smitt&Wesson вне форума Ответить с цитированием
Старый 30.10.2015, 08:58   #5
Andrej_K
Форумчанин
 
Регистрация: 27.07.2013
Сообщений: 256
По умолчанию

Код:
#include <stdio.h>

main (void)
{
	unsigned int i = 2;
	int k = 1;
	
	while (k < 70)
	{
		printf ("%d\n", i);
		i *= 2;
		k++;
	}
		
	return 0;
}
С unsigned int получается тот же результат. Странно…
И код тут не оформляется, хоть я и выбирал оформление.

Последний раз редактировалось Andrej_K; 30.10.2015 в 09:03.
Andrej_K вне форума Ответить с цитированием
Старый 30.10.2015, 09:09   #6
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

Цитата:
Сообщение от Smitt&Wesson Посмотреть сообщение
Ясно. У Вас int четырёхбайтный т.е. 32 разряда. Под конец вычислений, происходит переполнение положительной разрядной сетки. В старший разряд, заносится единица, что расценивается как отрицательный знак. Следующая итерация возведения в степень, начинает счёт с начала, т.е. с нуля.
Проставьте unsigned int, отрицательные числа исчезнут, но переход к нулю останется. Правда не на 33-й, а на 65-й итерации.
мои глаза.

> а int работает в диапазоне от -32767 до +32768
>У Вас int четырёхбайтный
а у тебя нет? на 286м сидишь?

> Самое большое положительное число в С++, вы можете получить используя тип unsigned long
ноуп. unsigned long long.

> но переход к нулю останется. Правда не на 33-й, а на 65-й итерации
ноуп. на 34-й. (хотя на самом деле на 33-й).

Цитата:
Сообщение от Andrej_K Посмотреть сообщение
Код:
#include <stdio.h>

main (void)
{
	unsigned int i = 2;
	int k = 1;
	
	while (k < 70)
	{
		printf ("%d\n", i);
		i *= 2;
		k++;
	}
		
	return 0;
}
С unsigned int получается тот же результат. Странно…
И код тут не оформляется, хоть я и выбирал оформление.
printf ("%u\n", i);
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось Stilet; 30.10.2015 в 09:19.
pproger вне форума Ответить с цитированием
Старый 30.10.2015, 09:15   #7
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
С unsigned int получается тот же результат. Странно…
ничего странного, мы же просим ВЫВЕСТИ как целое(имеющее знаковый разряд).
попробуй так
Код:
printf ("%u\n", i);
если не ошибаюсь (вывод целого БЕЗЗНАКОВОГО)
отрицательные исчезнут, но НОЛЬ останется.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 30.10.2015, 09:33   #8
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
мои глаза.

> а int работает в диапазоне от -32767 до +32768
>У Вас int четырёхбайтный
а у тебя нет? на 286м сидишь?

> Самое большое положительное число в С++, вы можете получить используя тип unsigned long
ноуп. unsigned long long.

> но переход к нулю останется. Правда не на 33-й, а на 65-й итерации
ноуп. на 34-й. (хотя на самом деле на 33-й).
Спросонья, ещё и не то на ум взбредёт.

Можно ещё коутом вывести. Но это С++, а не Си.

Код:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

int main ()
{
	unsigned long i = 1;
	int k = 1;

	while (k < 34)
	{
                cout << k << "  " << i << endl;
		//printf ("%u\n", i);
		i *= 2;
		k++;
	}
	system("pause");
	return 0;
}
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 30.10.2015, 10:08   #9
Andrej_K
Форумчанин
 
Регистрация: 27.07.2013
Сообщений: 256
По умолчанию

Не, я изучаю именно Си пока.
Изменил unsigned int на unsigned long — всё равно максимальное число 2147483648
Больше никак нельзя?
Andrej_K вне форума Ответить с цитированием
Старый 30.10.2015, 10:16   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А какова задача? Тебе наверное нужно работать с длинной арифметикой?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Что происходит в коде? Kirill3211 C# (си шарп) 5 12.12.2014 16:22
Что происходит с Вконтактом? Анна-22 Безопасность, Шифрование 44 06.05.2013 10:12
Коварный С++. Что происходит?! Начавший Общие вопросы C/C++ 3 07.12.2012 14:36
Происходит ли перераспределение памяти при присваивании динамических массивов одинаковых размеров? chertovich Общие вопросы Delphi 2 06.10.2012 13:02
Что происходит с сайтами? Smitt&Wesson Свободное общение 14 14.03.2012 11:11