powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / while(val != max) или while(val < max)
39 сообщений из 39, показаны все 2 страниц
while(val != max) или while(val < max)
    #39181878
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стандартная ситуация: есть некоторая числовая переменная 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
while(val != max) или while(val < max)
    #39181883
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если будет
Код: plaintext
1.
unsigned int val = 0;


то некоторые компиляторы будут ворнинги писать. в остальном пофиг, оба варианта идентичны если max имеет тот же тип что и val.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39181914
L.Otujktd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если max равен нулю то тело цикла вообще не выполнится в обоих случаях.сравнение через оператор < имхо более наглядное, те понятно что переменная val изначально меньше max и должна по логике к нему стремиться. В остальном обе проверки эквивалентны и можно использовать оба варианта. :)
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39181931
YesSql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
.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
while(val != max) или while(val < max)
    #39182023
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.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
while(val != max) или while(val < max)
    #39182046
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NET,

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

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



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

Если программа постоянно взаимодействует с пользователем, то да, а если это сервис?
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182111
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


Если поставить != ворнинга нет. И не зря компилятор предупреждает, т.к. данный пример сработает по-разному при < и !=.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182139
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.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
while(val != max) или while(val < max)
    #39182142
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NET Если программа постоянно взаимодействует с пользователем, то да, а если это сервис?

Зачем эти ограничения ?
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182179
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
while(val != max) или while(val < max)
    #39182196
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NETДа, это интересно, получается -1.
Сравнение беззнакового числа с отрицательным возвращает false.
Интересно, это прописано в стандарте или общепринятая практика?
Должно быть прописано в приведении типов. Тут знаковый тип приводится к беззнаковому, что фактически сводится просто к тому что int берется как unsigned int без каких либо изменений самого значения, для положительных это нормально, для отрицательных - нет, т.к. -1 хранится как 0xFFFFFFFF что > 100.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182215
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
while(val != max) или while(val < max)
    #39182218
YesSql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
while(val != max) или while(val < max)
    #39182221
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я почему-то ошибочно предполагал, что наоборот беззнаковый должен преобразовываться в знаковый.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182228
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
while(val != max) или while(val < max)
    #39182229
YesSql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
.NETЯ почему-то ошибочно предполагал, что наоборот беззнаковый должен преобразовываться в знаковый.
Только если все значения беззнакового типа помещаются в знаковый.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182764
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В С# по другому сделано.
Если знаковый складывается с максимальным по рангу беззнаковым (ulong), то вызывается исключение.
Если складываются знаковый и беззннаковый (не ulong) одного ранга, то оба аргумента приводятся
к знаковому следующего ранга.
Таким образом знак никогда не теряется.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182794
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
while(val != max) или while(val < max)
    #39182806
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С не C# тебе warning выдали а дальше сам решай: хочешь к большему приводи, хочешь тип меняй, хочешь != поставь. Приведение операция хоть и быстрая, но все-равно не бесплатная. И потом x32 приложения не быстро работают с Int64, т.к. нет 64-битных регистров.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182817
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tт.к. нет 64-битных регистров.
xmm регистры вполне пригодны для целочисленных вычислений. и 64, и 128 бит
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182820
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tx32 приложения не быстро работают с Int64, т.к. нет 64-битных регистров
Есть. И даже 128-битные есть.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39182853
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда хз почему тормозит
Код: 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
while(val != max) или while(val < max)
    #39182900
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чуть модифицировал тест для наглядности
Код: 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
while(val != max) или while(val < max)
    #39182935
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я-бы в большем отдавал предпочтение проверке на '<' (меньше) т.к.
она более строгая и математически чистая.

При миграции алгоритма к примеру в диапазон double или в численный
метод мы по крайней мере сможем обезопасить себя от вылетания за границу расчётов.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39183097
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне кажется, что такая нотация идёт из обобщённых алгоритмов STL.
Если у тебя while(i != j) {... ++j;}, то для изменения порядка обхода (произвольной) структуры с прямого на обратный не потребуется ничего менять в алгоритме - только подай в шаблон reverse iterator вместо обычного forward iterator. А вот с '<' вместо '!=' так уже не получится... так сказать, расплата за "гибкость-универсальность".
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39183145
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BagaBagaМне кажется, что такая нотация идёт из обобщённых алгоритмов STL.скорее всего, ибо на некоторых итераторах оператор < не реализуется, а оператор != - допустим всегда.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39183158
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NET Чтобы разобраться во всех ли случаях вариант с использованием != однозначно лучше.

Давайте разберёмся во всех случаях. В вашем случае инкремент равен единице. В других случаях он может быть практически любым. Вы рассматриваете только один вариант из очень большого числа(пусть он и встречается столько раз, как все остальные вместе взятые), потому никаких выводов делать пожалуй не стоит.
А эту историю с signed/unsigned знаю даже, далеко не самый опытный в Си человек
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39183532
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury.NET Чтобы разобраться во всех ли случаях вариант с использованием != однозначно лучше.

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

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

SashaMercuryА эту историю с signed/unsigned знаю даже, далеко не самый опытный в Си человек
Да я тоже "знаю" но периодически забываю, так как программировал профессионально только на C#,
а там всё наоборот, т. е. если в выражении участвует знаковый и беззнаковый, то оба приводятся к знаковому.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39183548
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychBagaBagaМне кажется, что такая нотация идёт из обобщённых алгоритмов STL.скорее всего, ибо на некоторых итераторах оператор < не реализуется, а оператор != - допустим всегда.

Та же история что и с постфиксным и префиксным инкрементом для числовых всё равно ++x или x++,
а для итераторов нет, поэтому считается что писать ++x предпочтительнее в любых случаях.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184318
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В одном учебнике пишут, что использование "val != max" предпочтительнее "val < max",
потому что в этом случае мы будем уверены, что после выполнения цикла val будет в точности равно мах,
во втором случае оно может быть и больше.
Другими словами "val != max" явно декларирует, что в результате работы цикла не предполагается ни в каком случае выход val
за границу max. Это упрощает понимание кода, тому кто будет читать его.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184332
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NETВ одном учебнике пишут, что использование "val != max" предпочтительнее "val < max",
потому что в этом случае мы будем уверены, что после выполнения цикла val будет в точности равно мах,
во втором случае оно может быть и больше.
Другими словами "val != max" явно декларирует, что в результате работы цикла не предполагается ни в каком случае выход val
за границу max. Это упрощает понимание кода, тому кто будет читать его.Что значит упрощает понимание? А с чего вдруг человек увидевший while(val < max) должен думать что по выходу из цикла val==max???
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184353
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NET, нарисуй вещественную ось. И покрытие двух условий. Одно из них - это выколотая точка.
Другое - луч от точки до бесконечности не включая саму точку.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184390
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.NETВ одном учебнике пишут

А что за учебник ?
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184512
.NET
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl.NETВ одном учебнике пишут, что использование "val != max" предпочтительнее "val < max",
потому что в этом случае мы будем уверены, что после выполнения цикла val будет в точности равно мах,
во втором случае оно может быть и больше.
Другими словами "val != max" явно декларирует, что в результате работы цикла не предполагается ни в каком случае выход val
за границу max. Это упрощает понимание кода, тому кто будет читать его.Что значит упрощает понимание? А с чего вдруг человек увидевший while(val < max) должен думать что по выходу из цикла val==max???
Он и не будет так думать (будет находиться в неведении), если использовать val < max.
Он будет думать (уверен), что val==max, если используется val != max.
Поэтому если по задумке программиста пишущего код val не должен выходить за границу max,
то и не стоит давать читающему код повода так думать используя val < max в условии выхода из цикла.

SashaMercuryА что за учебник ?


Accelerated C++ Andrew Koening, Barbara Moo
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184533
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Процитируйте пожалуйста, если вас не сильно затруднит. Первый автор известный товарищ, только фамилия у него Koenig, если не ошибаюсь, а второго я не знаю.
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184536
jmp_original
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
.NETWhite Owlпропущено...
Что значит упрощает понимание? А с чего вдруг человек увидевший while(val < max) должен думать что по выходу из цикла val==max???
Он и не будет так думать (будет находиться в неведении), если использовать val < max.
Он будет думать (уверен), что val==max, если используется val != max.
Поэтому если по задумке программиста пишущего код val не должен выходить за границу max,
то и не стоит давать читающему код повода так думать используя val < max в условии выхода из цикла.
*Делает наивное лицо* А разве в Си не принято, что val вообще не существует при выходе из цикла?
...
Рейтинг: 0 / 0
while(val != max) или while(val < max)
    #39184550
YesSql
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
.NETОн и не будет так думать
.NETОн будет думать

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

Да, фамилия первого автора Koenig, я ошибся.

Another reason to count from 0 is that we have to option of using != as our comparison
instead of <=. This distinction may seem trivial, but it affects what we know about the state
of program then loop finished. For example, if the condition is r != rows , then when the loop
finishes, we know that r == rows . Because the invariant says that we have written
r rows of output, we know that we have written exactly rows rows all told.
On the other hand, if the condition is r <= rows , then all we can prove is that we have written
at least rows rows of output. For all we know, we might have written more.
...
Рейтинг: 0 / 0
39 сообщений из 39, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / while(val != max) или while(val < max)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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