powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / while(val != max) или while(val < max)
25 сообщений из 39, страница 1 из 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
25 сообщений из 39, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / while(val != max) или while(val < max)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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