Re[17]: Эх, товарищ, товарищ...
От: Erlond Россия  
Дата: 15.11.06 17:51
Оценка: -1
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, Erlond, Вы писали:


E>>Ну почему же, всё зависит от задачи. Если разница между двумя unsigned не превышает INT_MAX, то следующий код вполне работоспособен.


E>>
E>>unsigned int i = 3;
E>>unsigned int j = 5;
E>>int r = i-j;
E>>std::cout << "r = " << r << std::endl;
E>>

E>>Результат:
E>>
E>>r = -2
E>>


vsb>Строго говоря, здесь, по 4.7.3, implementation-defined behaviour.



4.7.3
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and
bit-field width); otherwise, the value is implementation-defined.


Строго говоря — да, но если разница между двумя unsigned превышает INT_MAX, то должно работать, или я не прав?
Re[14]: unsigned
От: Пётр Седов Россия  
Дата: 15.11.06 18:14
Оценка: 36 (1) +1
Здравствуйте, Erlond, Вы писали:

E>Интересные аргументы приводятся "противниками" типа unsigned int.

Вряд ли здесь есть противники unsigned. Этот тип хорошо подходит для танцев с битами. Речь идёт об опасности беззнаковой арифметики.

E>В основном всё сводится к тому, что "ну не надо знаковую величену представлять безннаковой".

Нет, речь идёт о том, чтобы использовать int даже для неотрицательных ("зуб даю") чисел.

E>Количество — unsigned int, а разница — int.

Без приведений типа разница — тоже unsigned.

E>И ещё меня, допустим, удивляет реализация CArray, где метод GetSize() возвращает int.

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

E>Размер массива может быть отрицательным??

Нет, длина массива всегда >= 0. Но в одном выражении с CArray::GetSize может участвовать отрицательное число. Если ошибочный результат подвыражения не сохраняется в переменной, то ошибку найти тяжело. Например, здесь
Автор: Кирпа В.А.
Дата: 20.09.04
.

E>А программист должен знать типы данных языка.

Да. Например, желательно знать, что unsigned char и unsigned short в выражениях продвигаются (promote) до int (а не unsigned) и не вызывают беззнаковую арифметику (на современных платформах).
Также в языках C/C++ нет типов unsigned float и unsigned double, но пока никто не жаловался, что масса (объём, ...) хранится в переменной знакового типа. Аргументов вроде "Разве может масса быть отрицательной?" не слышно.

E>С++ не прощает легкомысленного программирования.

Да, поэтому отладочные проверки нужно делать самостоятельно. Например, с помощью assert-а.

R>>Но никакого "а типа вроде как количество товара не может быть отрицательным... заведу-ка я для него unsigned... ой а что это у меня получилось 4 миллиарда товаров?".

E>А что, лучше когда у нас получается -5 единиц товара?
Конечно лучше. Ближайший assert обнаружит это:
int Count;
...
assert(Count >= 0);

В случае unsigned условие бессмысленно.

E>Почему странно получить 4 млрд, а -5 — нормально?

Это не нормально, это ошибка, но в случае int-а её можно обнаружить, а в случае unsigned — нет.

E>P.S. Андрею Тарасевичу — большой респект

За что? За то, что направляет новичков на грабли (беззнаковая арифметика)?
Пётр Седов (ушёл с RSDN)
Re[15]: unsigned
От: Андрей Тарасевич Беларусь  
Дата: 15.11.06 19:22
Оценка: 55 (4) +1
Здравствуйте, Пётр Седов, Вы писали:

ПС>Здравствуйте, Erlond, Вы писали:


E>>Интересные аргументы приводятся "противниками" типа unsigned int.

ПС>Вряд ли здесь есть противники unsigned. Этот тип хорошо подходит для танцев с битами. Речь идёт об опасности беззнаковой арифметики.

Опасность — выдуманная.

E>>Количество — unsigned int, а разница — int.

ПС>Без приведений типа разница — тоже unsigned.

Значит надо не забывать делать приведение типа. Тут есть два очень важный момента, которые здесь уже упоминались.

Во-первых, приведение типа в данном случае — это не какой-то "странный каприз" спецификации языка, это преход между двумя приниципиально различными по своей природе арифметиками — обычной и модульной. Такой преход — событие настолько существенное, что делать его неявно в любом случае не стоит и, по этой причине, выполнение явного приведения типа более чем оправдано. Таких моментов в С/С++ навалом и избежать их не удастся отказом от безнаковых типов.

Во-вторых, в обычной арифметике в общем случае при вычитании двух N-битных чисел получается N+1-битное число. Это относится в одинаковой мере и к знаковым и к беззнаковым типам. То использование знаковых типов, которое пропагандируют тут противники беззнаковых, это в большинстве своем попытка закрыть глаза на существование этой проблемы на основании того, что работая рядом с "центром" диапазона знаковых чисел мы якобы находимся в болшей безопасности, чем работая рядом с "краем" беззнакового диапазона. Это ложная безопасность. С точки зрения достижения такой безопасности, всем следовало бы пользоваться самым большим знаковым типом ('long' или в C99 'long long') и это было бы самым "безопасным" и "защищенным от ошибок" вариантом. А все остальные типы объявим ненужными, предназначеннными для "экономии битов" в рамках разных (и, без сомнения, преждевременных) оптимизаций.

В реальности же закрывать глаза на проблему диапазона типа нельзя никогда, независимо от того знаков тип или беззнаков.

E>>И ещё меня, допустим, удивляет реализация CArray, где метод GetSize() возвращает int.

ПС>Это перестанет удивлять после дня, потраченного на поиск ошибки из-за беззнаковой арифметики.

Во-первых, я слышал аналогичные аргументы сторонников стиля 'if (5 == i)' — якобы запись 'if (i == 5)' приводит к ошибкам, которые потом надо будет искать днями. Реальность же показывает, что это не так.

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

Интерсно, кстати, наблюдать, как оппоненты беззнаковых типов приводят тут примеры ошибок в их использовании, считая что эти примеры демонстрируют недостатки беззнаковых типов, в то время как на самом деле эти примеры демонстрируют одно из огромных практических преимуществ этих типов: ошибочный беззнаковый код как правило проявляет свою ошибочность сразу, практически на любом тестовом примере, в то время как ошибчный знаковый код зачастую проявляет свою ошибочность только на особо неудачном тестовом примере.

R>>>Но никакого "а типа вроде как количество товара не может быть отрицательным... заведу-ка я для него unsigned... ой а что это у меня получилось 4 миллиарда товаров?".

E>>А что, лучше когда у нас получается -5 единиц товара?
ПС>Конечно лучше. Ближайший assert обнаружит это:
ПС>
ПС>int Count;
ПС>...
ПС>assert(Count >= 0);
ПС>

ПС>В случае unsigned условие бессмысленно.

Разумеется, бессмысленно. Потому что не нужно.

E>>Почему странно получить 4 млрд, а -5 — нормально?

ПС>Это не нормально, это ошибка, но в случае int-а её можно обнаружить, а в случае unsigned — нет.

Неверно. Просто использован типичный для знакового программирования порочный "посметрный" способ обнаружения ошибки.
Best regards,
Андрей Тарасевич
Re[13]: Ответ другого оппонента :)
От: Андрей Тарасевич Беларусь  
Дата: 16.11.06 05:16
Оценка: 14 (2) :))) :)
Здравствуйте, Erop, Вы писали:

АТ>>(Другому оппоненту: а модульную арифметику, кстати, тоже придумали математики...)


E>ваша правда, товарищ эксперт, но таки когда математики думали о модульной арифметике, они как-то не ограничивали себя в выборе модуля между 0x100, 0x10000, 0x100000000 и 0x10000000000000000


Это еще что! Когда они думали об обычной арифметике, они также не ограничивали себя диапазоном -0x80000000..0x7FFFFFFF. И даже диапазоном 0x8000000000000000..0x7FFFFFFFFFFFFFFF не ограничивали! Я слышал историю про то, как в древности один мужик за изобретение какой-то игры (поддавки, кажется) затребовал 2^64-1 пшеничных зерна. И это было тогда, до инфляции...
Best regards,
Андрей Тарасевич
Re[11]: Где тут ошибка
От: Максим2006 Беларусь  
Дата: 16.11.06 07:50
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

[]

АТ>Может ли быть дельта между значениями отрицательной — это вопрос постановки задачи. Согласно сделанной тобой постановке, эта величина может быть отрицательной. Прекрасно — это означает, что даннная величина будет представлена знаковым значением.


АТ>Вот и все.


Тут нужно уточнить каким знаковым. Если имеется в виду знаковое, по числу битов равное беззнаковому (int и unsigned int), то, наверное, не всё так просто (как хотелось бы). Ведь разность двух беззнаковых может дать как отрицательное значение, так и положительное. При этом в обоих этих случаях возможно непопадание в диапазон signed int. Как же тут быть? Может быть всегда использовать знаковое с более широким диапазоном? Наверное, всё зависит от конкретных допустимых значений в выражениях...

АТ>Я подозреваю, что следующим шагом будет попытка убедить меня в том, что "очень легко ошибиться" при вычитании первого из второго, т.е. забыть перевести вычисления в рамки знаковых типов. Над подобными аргументами можно только посмеяться.

Согласен
Re[14]: Ответ другого оппонента :)
От: Erlond Россия  
Дата: 16.11.06 07:56
Оценка: 3 (1) :)
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, Erop, Вы писали:


АТ>>>(Другому оппоненту: а модульную арифметику, кстати, тоже придумали математики...)


E>>ваша правда, товарищ эксперт, но таки когда математики думали о модульной арифметике, они как-то не ограничивали себя в выборе модуля между 0x100, 0x10000, 0x100000000 и 0x10000000000000000


АТ>Это еще что! Когда они думали об обычной арифметике, они также не ограничивали себя диапазоном -0x80000000..0x7FFFFFFF. И даже диапазоном 0x8000000000000000..0x7FFFFFFFFFFFFFFF не ограничивали! Я слышал историю про то, как в древности один мужик за изобретение какой-то игры (поддавки, кажется) затребовал 2^64-1 пшеничных зерна. И это было тогда, до инфляции...


Вообще-то это были шахматы, а дело было в Древней Индии. В оригинале было так:какому-то мудрецу поруили придумать военную игру, дабы правителю Индии не было скучно. Он придумал шахматы, и когда изобретателя шахмат спросили, что он хочет в награду за изобретение игры, он ответил так — "на 1 клетку доски положите мне 1 зерно, на 2-ю — два, на 3-ю 4 зерна..", и т.д.
Правитель посмеялся над этим, и распорядися выдатть ему зерно. Но... его расстроили математики — они считали несколько недель, какое количество зерён требуется выдать, а потом объявили, что такого колоичества зерна нету во всей Индиии...

Как вариант решения — заставить изобретателя отсчитывать вручную зёрна, много бы не насчитал
Re[13]: А ради чего таки все эти усилия? :)
От: Erop Россия  
Дата: 16.11.06 12:00
Оценка: +1
Здравствуйте, Centaur, Вы писали:

C>Вот так арифметика устроена, что при сложении/вычитании двух произвольных k-битных чисел в результате получается (k+1)-битное. И независимо от знаковости приходится думать — то ли у нас значения таковы, что переполнения никогда не будет, то ли нам важна качественная картина, а младшим битом можно пожертвовать (и хранить (a+b)/2 вместо a+b), то ли вообще реализовать сложение/вычитание с насыщением.


Ну в подавляющем большинстве случаев, когда речь идёт о числах, надо просто брать достаточно большое целое, чтобы с запасом хватало.
Если от чего-то так нельзя, тггда начинается суровая оптимизация и всякие малочитабельные, трудноредактируемые и не особо переносимые подпрыгивания с бубнами.
Кто бы спорил.

Но всякие "обычные случаи" вроде итерации массива или подсчёта производительности Васи -- они-то тут при чём?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[15]: Ответ другого оппонента :)
От: Аноним  
Дата: 16.11.06 12:07
Оценка: +3
Сдается мне, что Андрей прекрасно знает эту сказку и его слова про "некоего мужика", который "изобрел поддавки" — это типа шутка
Re[12]: Видимо ошибка в кончерватории :)
От: Erop Россия  
Дата: 16.11.06 12:07
Оценка:
Здравствуйте, Максим2006, Вы писали:

М>Тут нужно уточнить каким знаковым. Если имеется в виду знаковое, по числу битов равное беззнаковому (int и unsigned int), то, наверное, не всё так просто (как хотелось бы). Ведь разность двух беззнаковых может дать как отрицательное значение, так и положительное. При этом в обоих этих случаях возможно непопадание в диапазон signed int. Как же тут быть? Может быть всегда использовать знаковое с более широким диапазоном? Наверное, всё зависит от конкретных допустимых значений в выражениях...


Тем не менее в простых задачах. Вроде учёта производительност Васи, итерации массива, который находится в памяти, работы с размерами окон и т. п. всегда можно выбрать такой целый знаковый тип, что если вы не будете как-то особенно усиленно хаметь, то никакого переполнения не встретите. И будет вам счастье.

Ну а если вы пишете код, который расчитывает на специфицированное поведение при переполнении unsigned, и считаете его понятным и переносимым (от чего-так -- я совершенно не понимаю Вот скажем такая простая штука, как unsigned(-1) % 10 уже равна неизвестно чему), то конечно я не могу засавить вас посмотреть на мир, где можно писать целочисленные вычисления вообще без переполнений, но зачем вы остальных уверяете что это невозхможно я не понимаю
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[18]: Эх, товарищ, товарищ...
От: Erop Россия  
Дата: 16.11.06 12:15
Оценка: -1
Здравствуйте, Erlond, Вы писали:

E>Строго говоря — да, но если разница между двумя unsigned превышает INT_MAX, то должно работать, или я не прав?

Нифига не так.
Предатавь себе, что знаковые числа хранятся в виде мантисы и знака, например
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[16]: Нет бы вот ответить ясно, а не пальцами кидаться :)
От: Erop Россия  
Дата: 16.11.06 12:57
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Во-первых, приведение типа в данном случае — это не какой-то "странный каприз" спецификации языка, это преход между двумя приниципиально различными по своей природе арифметиками — обычной и модульной. Такой преход — событие настолько существенное, что делать его неявно в любом случае не стоит и, по этой причине, выполнение явного приведения типа более чем оправдано. Таких моментов в С/С++ навалом и избежать их не удастся отказом от безнаковых типов.



Собсвтенно язык C++ в области целых чисел довольно убогий. Увы и ах.
Есть всего два варианта целых типов.

Один реализует знаковую арифметику, в которой нельзя оперировать слишком большими (обычно не всегда известно насколько большими) числами, и второй -- модульная арифметика по не всегда известному нам заранее модулю.

Почему я пишу ""по неизвестному заранее", "неизвестно заранее насколько большие" и т. п.?
Да потому что разрядность сишных целых никто не гарантирует

Так что если у вас есть реальная угроза переполнения, то всё и всегда очень плохо. Хоть знаковый он у вас, хоть беззнаковый

Ну а теперь Внимаение! Вопрос!!!

Почему я должен считать, что величины: "число деталей", "длина массива", "ширина окна", "сумма денег в кошельке" лучше выражаются модульной арифметикой по неизвестному модулю, а не знаковой, с неизвестно гден наступающим переполнением?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: А ради чего таки все эти усилия? :)
От: Centaur Россия  
Дата: 16.11.06 13:42
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Ну в подавляющем большинстве случаев, когда речь идёт о числах, надо просто брать достаточно большое целое, чтобы с запасом хватало.


E>Если от чего-то так нельзя, тггда начинается суровая оптимизация и всякие малочитабельные, трудноредактируемые и не особо переносимые подпрыгивания с бубнами.

E>Кто бы спорил.

Лично в моей практике «так нельзя» сплошь и рядом. Вот есть 8-битный беззнаковый битмэп размера 320 на 240, от него нужно посчитать производную d/dx. Если я продвину его до знакового 16-битного:

Вот ещё пример того, как не подумали над разрядностью. Это размеры файлов. Сплошь и рядом их держат в 32-битных переменных. Иногда даже знаковых. Очень весело смотреть, как прыгают индикаторы прогресса и средней скорости скачивания в FTP-клиенте при переходе через 2G, потом через 4G, и так далее.

Думать надо всегда, и никакие типы от этого не избавляют. Сегодня Вася делает 400 деталей в день, а завтра их сложат по всем рабочим завода за 30 лет, умножат на стоимость детали в японских йенах, и привет.
Re[17]: Нет бы вот ответить ясно, а не пальцами кидаться :)
От: saproj  
Дата: 16.11.06 13:42
Оценка:
Здравствуйте, Erop, Вы писали:

E>Собсвтенно язык C++ в области целых чисел довольно убогий. Увы и ах.

E>Есть всего два варианта целых типов.

E>Один реализует знаковую арифметику, в которой нельзя оперировать слишком большими (обычно не всегда известно насколько большими) числами, и второй -- модульная арифметика по не всегда известному нам заранее модулю.


E>Почему я пишу ""по неизвестному заранее", "неизвестно заранее насколько большие" и т. п.?

E>Да потому что разрядность сишных целых никто не гарантирует

Детский сад! Вы уж простите меня. <climits> и <limits> позволяют писать программы, которые правильно заработают на платформах с разной разрядностью.

E>Так что если у вас есть реальная угроза переполнения, то всё и всегда очень плохо. Хоть знаковый он у вас, хоть беззнаковый


А еще память может не выделиться. Это тоже очень плохо?

E>Ну а теперь Внимаение! Вопрос!!!


E>Почему я должен считать, что величины: "число деталей", "длина массива", "ширина окна", "сумма денег в кошельке" лучше выражаются модульной арифметикой по неизвестному модулю, а не знаковой, с неизвестно гден наступающим переполнением?


Довод что верхний предел выше, а програма понятнее вам не кажется убедительным?
Re[14]: Закон перехода количества в качество.
От: Erop Россия  
Дата: 16.11.06 14:01
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Это еще что! Когда они думали об обычной арифметике, они также не ограничивали себя диапазоном -0x80000000..0x7FFFFFFF. И даже диапазоном 0x8000000000000000..0x7FFFFFFFFFFFFFFF не ограничивали! Я слышал историю про то, как в древности один мужик за изобретение какой-то игры (поддавки, кажется) затребовал 2^64-1 пшеничных зерна. И это было тогда, до инфляции...


Что-то мне подсказывает, что он таки столкнулся с переполнением, при попытке взыскать долг
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Нужен ли unsigned
От: Максим2006 Беларусь  
Дата: 16.11.06 14:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я решил попробовать писать "правильный" код. Для ширины например — unsigned, т.е. она не бывает отрицательной. И тд.

А>Но как меня всякие мелочи задолбали, извините. Чуть чуть перепутал, и всё, 4 миллиарда, вся логика валится.
А>Если int-ы хоть можно проверить на -1, то unsigned-ы как проверишь? Непонятно.
А>Собственно вопрос, оправдан ли такой геморрой? Или сделать :%s/unsigned/int/g и жить счастливой жизнью?
А>С одной стороны вроде бы unsigned идеологически лучше. Но с другой, не получается у меня нормально с ними писать. Каждый раз, когда фунцию с аргументом типа unsigned вызываешь, надо проверять, не передастся ли туда отрицательное число, а если бы она была int, то проверку можно было бы сделать внутри функции (ну не писать же
А>
А>void f(unsigned x)
А>{
А>    if ((int)x < 0) // something bad
А>}
А>
)

А>Что вы думаете по этому поводу?

Предлагаю послушать старейшин... (Б.Стр-п, 2005)

4.4 ...
...
Типы unsigned идеально подходят для задач, в которых память интерпретируется как массив битов. Использование unsigned вместо int с целью заработать лишний бит для представления положительных целых почти всегда оказывается неудачным решением. Использование же объявления unsigned для гарантии того, что целое будет неотрицательным, почти никогда не сработает из-за правил неявного преобразования типов.
...


Лично я до сих пор руководствовался тем принципом, что если объект, который представляет переменная, неотрицателен по смыслу, то лучше использовать unsigned. Это отражает смысл, помогает читать и понимать код. Это можно сравнить по красоте с модификатором const...

В то же время, я рассчитываю на поведение unsigned как отдельного типа, со схожим с int поведением. Но это не так. Например, выход за границу диапазона не является UB.

Было бы лучше иметь два разных типа — один для модульной арифметики, а второй — для беззнаковой (с UB при выходе за границы и иными правилами преобразования)
Re[15]: А ради чего таки все эти усилия? :)
От: Erop Россия  
Дата: 16.11.06 14:12
Оценка: +1
Здравствуйте, Centaur, Вы писали:

C>Думать надо всегда, и никакие типы от этого не избавляют. Сегодня Вася делает 400 деталей в день, а завтра их сложат по всем рабочим завода за 30 лет, умножат на стоимость детали в японских йенах, и привет.


Конечно думать надо всегда.
Просто когда речь идёт о знаковом целом, то думать надо как бы один раз. Сразу выяснить есть ли маза переполнить или нет.
Если таки есть -- прийдётся переходить на double или ещё чего дклать.

А в unsigned С++ числах надо думать о переполнении при кодировании кадой операции.
Ради чего это (кроме как радо того, чтобы не расслабляться) я так и не понял. Какая выгода от увеличения трудоёмкости кодирования?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[18]: Нет бы вот ответить ясно, а не пальцами кидаться :)
От: Erop Россия  
Дата: 16.11.06 14:22
Оценка: +1
Здравствуйте, saproj, Вы писали:

S>Детский сад! Вы уж простите меня. <climits> и <limits> позволяют писать программы, которые правильно заработают на платформах с разной разрядностью.



Вот смотри. Есть у тебя Вася. Рожает о детали в таких вот масштабах.
И всё-то у него хорошо. И пишешь ты про него программу. И у тебя всё хорошо. И ты даже файл limits умеешь использовать.
но беда в ся в том, что что же тебе делать, если ты выясняешь, что васины детали на этой конкретной платформе не помещаются в int?
Во всех плюсах понаписать всяких волшебных проверок? И если проверки провалились, то делать что?


E>>Так что если у вас есть реальная угроза переполнения, то всё и всегда очень плохо. Хоть знаковый он у вас, хоть беззнаковый

S>А еще память может не выделиться. Это тоже очень плохо?
Конечно. Обычно программы когда памяти не хватает просто отказываются работать и всё. В принципе последствия катастрофические

E>>Ну а теперь Внимаение! Вопрос!!!

E>>Почему я должен считать, что величины: "число деталей", "длина массива", "ширина окна", "сумма денег в кошельке" лучше выражаются модульной арифметикой по неизвестному модулю, а не знаковой, с неизвестно гден наступающим переполнением?

S>Довод что верхний предел выше, а програма понятнее вам не кажется убедительным?

1) Закладываться на то, что "верхний предел выше" в задае про Вася и детали крайне плохо. плохо потому, что то, что в signed величина не помещается, а в unsigned помещается -- это случайное стечение обстоятельств. Когда переполнение столь близко все вычисления надо вести очень аккуратно, всюду анализируя и проверяя возможность переполнения.

Намного позитивнее писать так, чтобы возможности переполнения вообще не было. Скажм Вася делает детали тысячами, а ты используешь 32-тный int. Тогда опасными становятся только квадраты количества деталлей. А всякие суммы-разности-ленейные комбинации нифига не опасны.

Зачем в такой ситуации связываться с unsigned?
Слово "зачем" подразумевает, что есть какая-то выгода.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[19]: Нет бы вот ответить ясно, а не пальцами кидаться :)
От: Аноним  
Дата: 16.11.06 14:29
Оценка: -1
E>Вот смотри. Есть у тебя Вася. Рожает о детали в таких вот масштабах.
E>И всё-то у него хорошо. И пишешь ты про него программу. И у тебя всё хорошо. И ты даже файл limits умеешь использовать.
E>но беда в ся в том, что что же тебе делать, если ты выясняешь, что васины детали на этой конкретной платформе не помещаются в int?
E>Во всех плюсах понаписать всяких волшебных проверок? И если проверки провалились, то делать что?

"Игривость" твоих сообщений и "простота" в общении уже несколько запарили. Если ты хорошо знаешь С/С++, то знаешь, что есть определенные гарантии для целочисленных типов. Переносимые программы на С/С++ вполне успешно пишутся, наверное потому, что люди их пишут а не тратят время на флейм о кошмарном ужасе беззнаковых.
Re[13]: Видимо ошибка в кончерватории :)
От: Максим2006 Беларусь  
Дата: 16.11.06 14:30
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Максим2006, Вы писали:


М>>Тут нужно уточнить каким знаковым. Если имеется в виду знаковое, по числу битов равное беззнаковому (int и unsigned int), то, наверное, не всё так просто (как хотелось бы). Ведь разность двух беззнаковых может дать как отрицательное значение, так и положительное. При этом в обоих этих случаях возможно непопадание в диапазон signed int. Как же тут быть? Может быть всегда использовать знаковое с более широким диапазоном? Наверное, всё зависит от конкретных допустимых значений в выражениях...


E>Тем не менее в простых задачах. Вроде учёта производительност Васи, итерации массива, который находится в памяти, работы с размерами окон и т. п. всегда можно выбрать такой целый знаковый тип, что если вы не будете как-то особенно усиленно хаметь, то никакого переполнения не встретите. И будет вам счастье.

Что касается итерации по массиву, у меня и так счастье потому что с этой задачей практически не сталкиваюсь. За меня это делает стд-алгоритм. А коль уж приходится, то применяю нелюбимую Вами технику скользящего указателя. Какой смысл тратить время на вычисление индекса? да я покурить успею, если сложить все эти задержки на большом массиве!
В остальном согласен. К сожалению. Потому что идея unsigned мне очень нравится, но, к сожалению, язык её не поддерживает как хотелось бы.

E>Ну а если вы пишете код, который расчитывает на специфицированное поведение при переполнении unsigned, и считаете его понятным и переносимым (от чего-так -- я совершенно не понимаю Вот скажем такая простая штука, как unsigned(-1) % 10 уже равна неизвестно чему), то конечно я не могу засавить вас посмотреть на мир, где можно писать целочисленные вычисления вообще без переполнений, но зачем вы остальных уверяете что это невозхможно я не понимаю

Код, основанный на переполнении unsigned, лучше поместить в класс/нэймспейс с соответствующим названием, потому что интуитивно не понятно что имеется в виду под именем типа unsigned.
Вы может меня с кем-то спутали?.. Я никого не уверял, что невозможно "писать целочисленные вычисления вообще без переполнений"
Re[19]: Нет бы вот ответить ясно, а не пальцами кидаться :)
От: saproj  
Дата: 16.11.06 14:43
Оценка:
Здравствуйте, Erop, Вы писали:

E>>>Так что если у вас есть реальная угроза переполнения, то всё и всегда очень плохо. Хоть знаковый он у вас, хоть беззнаковый

S>>А еще память может не выделиться. Это тоже очень плохо?
E>Конечно. Обычно программы когда памяти не хватает просто отказываются работать и всё. В принципе последствия катастрофические
Ну вы, надеюсь, делаете проверку ошибок выделения памяти, чтобы программа хоть завершилась штатно, а не упала?

На остальное отвечать не буду, т.к. ваш тон не нравится.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.