Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / while(val != max) или while(val < max) / 25 сообщений из 39, страница 1 из 2
29.02.2016, 19:57
    #39181878
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Стандартная ситуация: есть некоторая числовая переменная val которая инкриментируется в цикле while.
Условием выхода из цикла является достижение значением переменной val некоторого максимального значения max.
В учебниках в этом случае обычно используют следующий код:

Код: plaintext
1.
2.
3.
4.
5.
6.
int val = 0;
while(val != max)
{
   // do something
   ++val;
}



Но почему собственно в условии цикла используется проверка на неравенство, а не проверка на меньше (val < max),
ведь последний вариант более надёжен?
Допустим в ходе выполнения цикла происходит сбой (ошибка в коде, сбой в работе компилятора, аппаратный сбой и т. д.)
и итерация на которой val == max пропускается или проверка условия выполняется с ошибкой,
тогда цикл, автоматически становиться бесконечным. Если же используется проверка на меньше,
то цикл завершиться на следующей итерации.
...
Рейтинг: 0 / 0
29.02.2016, 20:10
    #39181883
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Если будет
Код: plaintext
1.
unsigned int val = 0;


то некоторые компиляторы будут ворнинги писать. в остальном пофиг, оба варианта идентичны если max имеет тот же тип что и val.
...
Рейтинг: 0 / 0
29.02.2016, 21:01
    #39181914
L.Otujktd
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Если max равен нулю то тело цикла вообще не выполнится в обоих случаях.сравнение через оператор < имхо более наглядное, те понятно что переменная val изначально меньше max и должна по логике к нему стремиться. В остальном обе проверки эквивалентны и можно использовать оба варианта. :)
...
Рейтинг: 0 / 0
29.02.2016, 21:32
    #39181931
YesSql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NET
Код: plaintext
1.
2.
3.
4.
5.
6.
int val = 0;
while(val != max)
{
   // do something
   ++val;
}



Но почему собственно в условии цикла используется проверка на неравенство, а не проверка на меньше (val < max),
ведь последний вариант более надёжен?

Зависит от того что такое max. Если это константа - оба варианта хороши. Если max вычисляется, возможно и с участием пользовательских данных, то нет гарантии что оно не уйдет в отрицательные значения. Тогда однозначно val < max
...
Рейтинг: 0 / 0
01.03.2016, 01:55
    #39182023
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NETСтандартная ситуация: есть некоторая числовая переменная val которая инкриментируется в цикле while.
Условием выхода из цикла является достижение значением переменной val некоторого максимального значения max.
В учебниках в этом случае обычно используют следующий код:

Код: plaintext
1.
2.
3.
4.
5.
6.
int val = 0;
while(val != max)
{
   // do something
   ++val;
}




стандартной ситуацией на Си/С++ в данном случае скорее будет использование оператора for, по причине наличия всех трёх блоков такого вида операторов.

.NET
Если же используется проверка на меньше,
то цикл завершиться на следующей итерации.

в первом случае, когда, как вы говорите, программа будет выполнять бесконечно, будет понятно о том что произошел какой-то сбой, что-то не так. В данном случае мы об этом не узнаем.
...
Рейтинг: 0 / 0
01.03.2016, 06:14
    #39182046
CEMb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NET,

Лучше тогда у тех авторов спросить. Может их в детстве мучили множествами, у которых отсутствует оператор "<". Для унификации или по привычке везде теперь пишут "!=", он-то на всём применим. В общем, мне непонятно.
...
Рейтинг: 0 / 0
01.03.2016, 08:58
    #39182082
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
SashaMercuryстандартной ситуацией на Си/С++ в данном случае скорее будет использование оператора for, по причине наличия всех трёх блоков такого вида операторов.

Да, истинный программист C/C++, побуждаемый желанием сэкономить количество дырочек на перфокарте, написал бы так:
Код: plaintext
1.
2.
3.
4.
5.
int val = 0;
while(val++ != max)
{
   // do something
}



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

Если программа постоянно взаимодействует с пользователем, то да, а если это сервис?
...
Рейтинг: 0 / 0
01.03.2016, 09:29
    #39182111
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Такой код компилируется с предупреждениями
Код: plaintext
1.
2.
3.
4.
5.
6.
	int v = -1;
	size_t max = 100;
	while(v < max) { // Warning	C4018	'<': signed / unsigned mismatch
		v++;
	}
	printf("%d\n", v); // Угадай чему равно v


Если поставить != ворнинга нет. И не зря компилятор предупреждает, т.к. данный пример сработает по-разному при < и !=.
...
Рейтинг: 0 / 0
01.03.2016, 10:03
    #39182139
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NETSashaMercuryстандартной ситуацией на Си/С++ в данном случае скорее будет использование оператора for, по причине наличия всех трёх блоков такого вида операторов.

Да, истинный программист C/C++, побуждаемый желанием сэкономить количество дырочек на перфокарте, написал бы так:
Код: plaintext
1.
2.
3.
4.
5.
int val = 0;
while(val++ != max)
{
   // do something
}





Этот участок кода не эквивалентен вашему первому варианту

Код: plaintext
1.
2.
3.
4.
5.
6.
int val = 0;
while(val != max)
{
   // do something
   ++val;
}
...
Рейтинг: 0 / 0
01.03.2016, 10:04
    #39182142
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NET Если программа постоянно взаимодействует с пользователем, то да, а если это сервис?

Зачем эти ограничения ?
...
Рейтинг: 0 / 0
01.03.2016, 10:29
    #39182179
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
SashaMercury.NET Если программа постоянно взаимодействует с пользователем, то да, а если это сервис?

Зачем эти ограничения ?
Чтобы разобраться во всех ли случаях вариант с использованием != однозначно лучше.

Dima TТакой код компилируется с предупреждениями
Код: plaintext
1.
2.
3.
4.
5.
6.
	int v = -1;
	size_t max = 100;
	while(v < max) { // Warning	C4018	'<': signed / unsigned mismatch
		v++;
	}
	printf("%d\n", v); // Угадай чему равно v


Если поставить != ворнинга нет. И не зря компилятор предупреждает, т.к. данный пример сработает по-разному при < и !=.
Да, это интересно, получается -1.
Сравнение беззнакового числа с отрицательным возвращает false.
Интересно, это прописано в стандарте или общепринятая практика?
...
Рейтинг: 0 / 0
01.03.2016, 10:52
    #39182196
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NETДа, это интересно, получается -1.
Сравнение беззнакового числа с отрицательным возвращает false.
Интересно, это прописано в стандарте или общепринятая практика?
Должно быть прописано в приведении типов. Тут знаковый тип приводится к беззнаковому, что фактически сводится просто к тому что int берется как unsigned int без каких либо изменений самого значения, для положительных это нормально, для отрицательных - нет, т.к. -1 хранится как 0xFFFFFFFF что > 100.
...
Рейтинг: 0 / 0
01.03.2016, 11:07
    #39182215
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Dima T,
Да есть такое

6.5.8 Relational operators3. If both of the operands have arithmetic type, the usual arithmetic conversions are
performed.


6.3.1.8 Usual arithmetic conversionsIf both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned
integer types, the operand with the type of lesser integer conversion rank is
converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.
...
Рейтинг: 0 / 0
01.03.2016, 11:09
    #39182218
YesSql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Dima T.NETДа, это интересно, получается -1.
Сравнение беззнакового числа с отрицательным возвращает false.
Интересно, это прописано в стандарте или общепринятая практика?
Должно быть прописано в приведении типов. Тут знаковый тип приводится к беззнаковому, что фактически сводится просто к тому что int берется как unsigned int без каких либо изменений самого значения, для положительных это нормально, для отрицательных - нет, т.к. -1 хранится как 0xFFFFFFFF что > 100.
Не всегда

попробуй так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	
        int v = -1;
	unsigned char max = 100;
	while(v < max) { // Warning	C4018	'<': signed / unsigned mismatch
		v++;
	}
	printf("%d\n", v); // Угадай чему равно v



преобразование выполняется по 6.3.1.8 "Usual arithmetic conversions"
...
Рейтинг: 0 / 0
01.03.2016, 11:12
    #39182221
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Я почему-то ошибочно предполагал, что наоборот беззнаковый должен преобразовываться в знаковый.
...
Рейтинг: 0 / 0
01.03.2016, 11:14
    #39182228
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
YesSqlDima Tпропущено...

Должно быть прописано в приведении типов. Тут знаковый тип приводится к беззнаковому, что фактически сводится просто к тому что int берется как unsigned int без каких либо изменений самого значения, для положительных это нормально, для отрицательных - нет, т.к. -1 хранится как 0xFFFFFFFF что > 100.
Не всегда

попробуй так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
	
        int v = -1;
	unsigned char max = 100;
	while(v < max) { // Warning	C4018	'<': signed / unsigned mismatch
		v++;
	}
	printf("%d\n", v); // Угадай чему равно v



преобразование выполняется по 6.3.1.8 "Usual arithmetic conversions"
Ну это понятно если размер знакового больше, то преобразуется в знаковый.
...
Рейтинг: 0 / 0
01.03.2016, 11:14
    #39182229
YesSql
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
.NETЯ почему-то ошибочно предполагал, что наоборот беззнаковый должен преобразовываться в знаковый.
Только если все значения беззнакового типа помещаются в знаковый.
...
Рейтинг: 0 / 0
01.03.2016, 16:21
    #39182764
.NET
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
В С# по другому сделано.
Если знаковый складывается с максимальным по рангу беззнаковым (ulong), то вызывается исключение.
Если складываются знаковый и беззннаковый (не ulong) одного ранга, то оба аргумента приводятся
к знаковому следующего ранга.
Таким образом знак никогда не теряется.
...
Рейтинг: 0 / 0
01.03.2016, 16:51
    #39182794
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
C# похоже к Int64 приводит оба.
так работает правильно
Код: c#
1.
2.
3.
4.
5.
6.
			Int32 v = -1;
			UInt32 max = 100;
			while(v < max) {
				v++;
			}
			Console.WriteLine(v); 


а так ошибка компиляции
Код: c#
1.
2.
3.
			Int64 v = -1;
			UInt64 max = 100;
			while(v < max) { // Error	CS0034	Operator '<' is ambiguous on operands of type 'long' and 'ulong'
...
Рейтинг: 0 / 0
01.03.2016, 16:58
    #39182806
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
С не C# тебе warning выдали а дальше сам решай: хочешь к большему приводи, хочешь тип меняй, хочешь != поставь. Приведение операция хоть и быстрая, но все-равно не бесплатная. И потом x32 приложения не быстро работают с Int64, т.к. нет 64-битных регистров.
...
Рейтинг: 0 / 0
01.03.2016, 17:06
    #39182817
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Dima Tт.к. нет 64-битных регистров.
xmm регистры вполне пригодны для целочисленных вычислений. и 64, и 128 бит
...
Рейтинг: 0 / 0
01.03.2016, 17:07
    #39182820
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Dima Tx32 приложения не быстро работают с Int64, т.к. нет 64-битных регистров
Есть. И даже 128-битные есть.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
01.03.2016, 17:27
    #39182853
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Тогда хз почему тормозит
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main(int argc, char**argv)
{
	int64_t v = 0;

	for (int64_t i = 0; i < 10000000000; i++) {
		v += (i & 3);
	}
	printf("%lld %d\n", v, clock());
	return 0;
}



x86 работает 5,4 сек, x64 - 5,0 сек. MSVC 2015
...
Рейтинг: 0 / 0
01.03.2016, 17:58
    #39182900
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
чуть модифицировал тест для наглядности
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
typedef int64_t test_t;
//typedef int32_t test_t;

int main(int argc, char**argv)
{
	test_t v = 0;

	for (test_t i = 0; i < 2000000000; i++) {
		v += (i & 3);
	}
	printf("%d ms %d\n", clock(), v);
	return 0;
}

РезультатСборка\test_tint_32int64x860.60 сек1.67 секx640.78 сек0.78 сек
PS странно что если int64 и i < 10000000000, то разбег незначительный, x86 - 5,4 сек, x64 - 5,0 сек.
...
Рейтинг: 0 / 0
01.03.2016, 18:29
    #39182935
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
while(val != max) или while(val < max)
Я-бы в большем отдавал предпочтение проверке на '<' (меньше) т.к.
она более строгая и математически чистая.

При миграции алгоритма к примеру в диапазон double или в численный
метод мы по крайней мере сможем обезопасить себя от вылетания за границу расчётов.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / while(val != max) или while(val < max) / 25 сообщений из 39, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]