Откуда эта лютая любовь к знаковым целым?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.05.20 02:56
Оценка: 21 (5) +5
Даже во многих современных программах на C++ часто вижу int/short/long там, где по смыслу должно быть беззнаковое целое. А в ранних программах знаковые целые вообще использовались везде, где было технически возможно. Даже в классической книге Кернигана/Ритчи множество примеров, где счетчики, индексы и прочие имеют знаковый тип. В виндовых SDK, где знаковость в основном используется адекватно, все равно регулярно встречаются знаковые параметры размеров, количеств и прочего, где не используются отрицательные значения для особых случаев.

Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?

09.05.20 12:07: Перенесено из 'Компьютерные священные войны'
10.05.20 22:31: Перенесено из 'Компьютерные священные войны'
short int long signed unsigned знаковые беззнаковые целые
Re: Откуда эта лютая любовь к знаковым целым?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.05.20 03:04
Оценка: +2 :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Даже во многих современных программах на C++ часто вижу int/short/long там, где по смыслу должно быть беззнаковое целое.


Писать зело больше


ЕМ>А в ранних программах знаковые целые вообще использовались везде, где было технически возможно. Даже в классической книге Кернигана/Ритчи множество примеров, где счетчики, индексы и прочие имеют знаковый тип. В виндовых SDK, где знаковость в основном используется адекватно, все равно регулярно встречаются знаковые параметры размеров, количеств и прочего, где не используются отрицательные значения для особых случаев.


Про отрицательные значения и то, что они не используются — ты не можешь быть уверен. Но таки да, может и по лени или недосмотру.


ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


Нет.

От тебя много батхерта последнее время. Тебя из РФ не выпускают, как я понимаю?
Маньяк Робокряк колесит по городу
Re: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 05.05.20 03:22
Оценка: 1 (1) +5 -6
Здравствуйте, Евгений Музыченко, Вы писали:

Знаковые целые тупо безопаснее. Беззнаковость в STL — это огромная историческая ошибка, даже Степанов это признал.
Ты на беззнаках даже тупо от ЭН до нуля проитерироваться не можешь без дополнительного бубна.
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.05.20 03:54
Оценка:
Здравствуйте, Marty, Вы писали:

M>Писать зело больше


О да, uint вместо int, ulong вместо long — это ж пальцы отобьешь...

M>Про отрицательные значения и то, что они не используются — ты не можешь быть уверен.


Что значит "не могу"? Если я по коду вижу, что особые случаи не предусмотрены — что еще нужно для уверенности? А если количество чего-то, по логике не превышающего, скажем, 1000, в результате ошибки окажется -10, то чем это может быть лучше 50000?

M>От тебя много батхерта последнее время.


Не больше, чем обычно. Так-то у меня сейчас дела идут сильно лучше, чем зимой, так что не в этом дело.

M>Тебя из РФ не выпускают, как я понимаю?


Сейчас уже вроде выпускают, но пока сообщение толком не наладилось. К середине месяца, надеюсь, что-то двинется.
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 05.05.20 04:00
Оценка: -2
Здравствуйте, T4r4sB, Вы писали:

TB>Знаковые целые тупо безопаснее.


В отдельных случаях — согласен. Но никак не в общем.

TB>Беззнаковость в STL — это огромная историческая ошибка, даже Степанов это признал.


В чем именно? Я не слежу за развитием STL.

TB>Ты на беззнаках даже тупо от ЭН до нуля проитерироваться не можешь без дополнительного бубна.


А насколько часто нужно повторять от N до нуля включительно? По-моему, это весьма частный случай, встречается очень редко. Какие есть типовые случаи?

Лично я с самого начала своей практики на C/C++ (начало 90-х) использую для счетчиков, количеств, размеров и прочего только беззнаковые. Случаев, подобных упомянутому, или неочевидных ошибок за это время были единицы. А вот проблем и глюков из-за бессмысленных преобразований туда-сюда, по причине знаковости функций CRT и API — сотни. Что я все это время делал не так?
Re[3]: Откуда эта лютая любовь к знаковым целым?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.05.20 04:19
Оценка: -2
Здравствуйте, Евгений Музыченко, Вы писали:

M>>Писать зело больше


ЕМ>О да, uint вместо int, ulong вместо long — это ж пальцы отобьешь...


Таких типов нет, если что


M>>Про отрицательные значения и то, что они не используются — ты не можешь быть уверен.


ЕМ>Что значит "не могу"? Если я по коду вижу, что особые случаи не предусмотрены — что еще нужно для уверенности? А если количество чего-то, по логике не превышающего, скажем, 1000, в результате ошибки окажется -10, то чем это может быть лучше 50000?


Может унутре используются. То, что к тебе отрицательные значения не попадают, это еще ничего не значит
Маньяк Робокряк колесит по городу
Re: Откуда эта лютая любовь к знаковым целым?
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 05.05.20 04:38
Оценка: 9 (5) +10 -1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


Что сразу вспомнилось:
1. Про итерирование от N до 0 уже написали, но повторюсь.
2. OpenMP. Неожиданно, но Майкрософт в своём компиляторе поддерживает только очень старую версию 2.0, в ней индексы для for могут быть только знаковыми.
3. Адресная арифметика вся знаковая, родной тип ptrdiff_t. То есть если я захочу сделать размеры картинки (ширину и высоту) сделать, например, size_t и ходить по изображению по байтам, то мне всё равно надо переходить к ptrdiff_t, чтобы компилятор не ругался.
4. Внезапно оказывается, что многие типы становятся знаковыми, хотя по логике они такими быть, на первый взгляд, не могут. Например, детектирую я пешеходов и авто на кадре. И их левая координата уходит в минус, если в кадре видна только часть автомобиля.
5. Далее знаковые становятся удобнее, когда происходит преобразование в другие системы координат. В твоей экранной системе координаты только положительные, ты рисуешь график в декартовой и числа внезапно становятся отрицательными.
6. Даже яркость пикселя, которая чаще всего от 0 до 255 и представлена в uchar при манипуляциях с яркостью легко вылезает за пределы типа вверх и вниз, поэтому тут либо ставить кучу проверок, либо при манипуляциях кастовать в int, а потом обратно. Хотя тут больше есть ограничение на тип, но если сделать его и uint64, легче не станет.

Получается, что большая часть моих кейсов сводится к тому, что естественные ограничения на беззнаковость идут к херам при вычислениях с этими типами. Насколько размер одного контейнера больше второго? Нельзя просто так взять и вычесть! Надо написать if (v1.size() > v2.size())...
Ну куда такое годится?
https://elibrary.ru/author_counter.aspx?id=875549
Отредактировано 05.05.2020 4:39 Nuzhny . Предыдущая версия .
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: Философ Ад http://vk.com/id10256428
Дата: 05.05.20 05:06
Оценка:
Здравствуйте, Marty, Вы писали:


ЕМ>>Даже во многих современных программах на C++ часто вижу int/short/long там, где по смыслу должно быть беззнаковое целое.

M>Писать зело больше

На одну букву — это сильно больше???


ЕМ>>А в ранних программах знаковые целые вообще использовались везде, где было технически возможно. Даже в классической книге Кернигана/Ритчи множество примеров, где счетчики, индексы и прочие имеют знаковый тип. В виндовых SDK, где знаковость в основном используется адекватно, все равно регулярно встречаются знаковые параметры размеров, количеств и прочего, где не используются отрицательные значения для особых случаев.


M>Про о трицательные значения и то, что они не используются — ты не можешь быть уверен. Но таки да, может и по лени или недосмотру.


Особенно, когда отрицательным значением задаются размеры в структурах: мы ведь не можем быть уверены, что переданный буфер не имеет отрицательного размера.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[3]: Откуда эта лютая любовь к знаковым целым?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.05.20 05:15
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>А насколько часто нужно повторять от N до нуля включительно? По-моему, это весьма частный случай, встречается очень редко. Какие есть типовые случаи?


От N-1 до нуля включительно — на самом деле хотелось бы весьма часто. Но так как size_t и его производные — беззнаковый, то я стараюсь обходится без такого. Хотя и неудобно бывает


ЕМ>Лично я с самого начала своей практики на C/C++ (начало 90-х) использую для счетчиков, количеств, размеров и прочего только беззнаковые.


Имхо это как раз стандартной библиотекой и привито


ЕМ>Случаев, подобных упомянутому, или неочевидных ошибок за это время были единицы.


Но таки были


ЕМ>А вот проблем и глюков из-за бессмысленных преобразований туда-сюда, по причине знаковости функций CRT и API — сотни. Что я все это время делал не так?


Так наверно преобразования возникали как раз из-за безнаковости плюсовых привычек, а АПИ хотят знаковые
Маньяк Робокряк колесит по городу
Re[3]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 05.05.20 05:23
Оценка: +1 -1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>А насколько часто нужно повторять от N до нуля включительно? По-моему, это весьма частный случай, встречается очень редко. Какие есть типовые случаи?


От нуля до N-1. На беззнаковых такой перебор записывается довольно неестественно.
Знак это дополнительный маркер, что мы вышли за диапазон в другую сторону.

ЕМ>Лично я с самого начала своей практики на C/C++ (начало 90-х) использую для счетчиков, количеств, размеров и прочего только беззнаковые. Случаев, подобных упомянутому, или неочевидных ошибок за это время были единицы. А вот проблем и глюков из-за бессмысленных преобразований туда-сюда, по причине знаковости функций CRT и API — сотни. Что я все это время делал не так?


А не надо было преобразовывать, надо было всё делать знаковым.

Ссылку на Степанова пока не помню, постараюсь найти.
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: GhostCoders Россия  
Дата: 05.05.20 06:10
Оценка: +1
Здравствуйте, Nuzhny, Вы писали:

N>Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


N>Что сразу вспомнилось:

N>1. Про итерирование от N до 0 уже написали, но повторюсь.
N>2. OpenMP. Неожиданно, но Майкрософт в своём компиляторе поддерживает только очень старую версию 2.0, в ней индексы для for могут быть только знаковыми.
N>3. Адресная арифметика вся знаковая, родной тип ptrdiff_t. То есть если я захочу сделать размеры картинки (ширину и высоту) сделать, например, size_t и ходить по изображению по байтам, то мне всё равно надо переходить к ptrdiff_t, чтобы компилятор не ругался.
N>4. Внезапно оказывается, что многие типы становятся знаковыми, хотя по логике они такими быть, на первый взгляд, не могут. Например, детектирую я пешеходов и авто на кадре. И их левая координата уходит в минус, если в кадре видна только часть автомобиля.
N>5. Далее знаковые становятся удобнее, когда происходит преобразование в другие системы координат. В твоей экранной системе координаты только положительные, ты рисуешь график в декартовой и числа внезапно становятся отрицательными.
N>6. Даже яркость пикселя, которая чаще всего от 0 до 255 и представлена в uchar при манипуляциях с яркостью легко вылезает за пределы типа вверх и вниз, поэтому тут либо ставить кучу проверок, либо при манипуляциях кастовать в int, а потом обратно. Хотя тут больше есть ограничение на тип, но если сделать его и uint64, легче не станет.

N>Получается, что большая часть моих кейсов сводится к тому, что естественные ограничения на беззнаковость идут к херам при вычислениях с этими типами. Насколько размер одного контейнера больше второго? Нельзя просто так взять и вычесть! Надо написать if (v1.size() > v2.size())...

N>Ну куда такое годится?
Таки да. Не особый фанат или знаток Java — но, насколько я помню, там типы — только знаковые из-за соображений безопасности (переполнения и т.п.).
Лично я сам использую С++ и использую беззнаковые типы, где это только можно. И по-опыту скажу — что никаких особых преимуществ это не дает,
часто делаю размер беззнаковым только потому, чтобы кто-то другой не стал бы тыкать пальцами, и "так надо".
Третий Рим должен пасть!
Re: Откуда эта лютая любовь к знаковым целым?
От: Stanislav V. Zudin Россия  
Дата: 05.05.20 06:14
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


К ранеесказанному добавлю ещё один кейс.
Индекс в массиве это полноценная сущность БД. Используется вместо указателей.
В этом случае отрицательные значения используются для обозначения невалидных объектов (у нас это -1) и для каких-нибудь специальных констант.
_____________________
С уважением,
Stanislav V. Zudin
Re: Откуда эта лютая любовь к знаковым целым?
От: Homunculus Удмуртия  
Дата: 05.05.20 06:20
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

Не знаю как вообще, но скажу за себя, почему не очень часто использую unsigned.
Во-первых, повидал кучу багов в коде других, когда это приводило к ошибкам, а чтоб ошибки не было, надо было доп условия ставить.
Во-вторых, иногда нужно не-валидное значение чего-то, что по смыслу неотрицательно. И для этого я лично использую «-1». И если переменная равна ему, то значит значение невалидное. Такая штука с unsigned не проканает, если не вводить всякие magic digits конечно.
Re: Откуда эта лютая любовь к знаковым целым?
От: Voivoid  
Дата: 05.05.20 06:40
Оценка: 9 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


в добавку к уже сказанному:

#include <iostream>

int main() {
  std::cout << ( -1 / 1u ) << std::endl;
  std::cout << ( -1 < 1u ) << std::endl;
  return 0;
}


https://ideone.com/BqNwCg
Re: Откуда эта лютая любовь к знаковым целым?
От: Шахтер Интернет  
Дата: 05.05.20 07:15
Оценка: -3 :))
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Даже во многих современных программах на C++ часто вижу int/short/long там, где по смыслу должно быть беззнаковое целое. А в ранних программах знаковые целые вообще использовались везде, где было технически возможно. Даже в классической книге Кернигана/Ритчи множество примеров, где счетчики, индексы и прочие имеют знаковый тип. В виндовых SDK, где знаковость в основном используется адекватно, все равно регулярно встречаются знаковые параметры размеров, количеств и прочего, где не используются отрицательные значения для особых случаев.


ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


Это из-за багов в генах.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 05.05.20 07:44
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Это из-за багов в генах.


Поясни. Тебе выкатили простыню из кучи случаев, где отсутствие знака в типе переменной провоцирует ошибки. Ты молча влепил минус без обоснования. Давай, поясняй.
Re[2]: Откуда эта лютая любовь к знаковым целым?
От: rg45 СССР  
Дата: 05.05.20 07:51
Оценка: 7 (2) +2 -1
Здравствуйте, T4r4sB, Вы писали:

TB>Ты на беззнаках даже тупо от ЭН до нуля проитерироваться не можешь без дополнительного бубна.


А в чем проблема?

http://coliru.stacked-crooked.com/a/b2e320d32ba56367

    short arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    for (size_t i = std::size(arr); i--;) {
        std::cout << arr[i] << " ";
    }
--
Говорить, что думаешь — это хорошо. Но еще лучше — думать, что говоришь.
Re: Откуда эта лютая любовь к знаковым целым?
От: Pavel Dvorkin Россия  
Дата: 05.05.20 08:00
Оценка: 6 (4) +8 -1 :)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


Операции, в которых участвуют исключительно знаковые аргументы, производятся по правилам обычной школьной арифметики (mod 2^31 держим в уме, конечно)
Операции, в которых используются исключительно беззнаковые аргументы, хороши, пока дело ограничивается арифметикой на уровне начальной школы — до того момента, когда в школе начинают изучать отрицательные числа. Вопрос о том, можно ли от 1 отнять 2, и что при этом будет, блокируется Марией Ивановной со словами "об этом вам расскажут в 5 классе"
Операции, в которых одновременно используются знаковые и беззнаковые аргументы, требуют внимательного рассмотрения в каждом случае — иначе можно такое получить, что не дай бог. Причем самое скверное, что получить это можно иногда в 0.01% случаев, так что и не протестируешь порой как следует.

Резюме — программистам, имеющим образование выше начальной школы, лучше использовать знаковые аргументы и не париться.
Исключение их правила : использование целого как битовой шкалы. В этом случае, естественно, лучше без знака, так как арифметики тут не предвидится.
With best regards
Pavel Dvorkin
Отредактировано 05.05.2020 8:01 Pavel Dvorkin . Предыдущая версия .
Re[3]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 05.05.20 08:07
Оценка: 1 (1) +3 :)
Здравствуйте, rg45, Вы писали:

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


TB>>Ты на беззнаках даже тупо от ЭН до нуля проитерироваться не можешь без дополнительного бубна.


R>А в чем проблема?


i--, заменяющее сразу два блока из заголовка for? Мы вам перезвоним, ога.
Re: Откуда эта лютая любовь к знаковым целым?
От: kov_serg Россия  
Дата: 05.05.20 08:15
Оценка: +5
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Даже во многих современных программах на C++ часто вижу int/short/long там, где по смыслу должно быть беззнаковое целое. А в ранних программах знаковые целые вообще использовались везде, где было технически возможно. Даже в классической книге Кернигана/Ритчи множество примеров, где счетчики, индексы и прочие имеют знаковый тип. В виндовых SDK, где знаковость в основном используется адекватно, все равно регулярно встречаются знаковые параметры размеров, количеств и прочего, где не используются отрицательные значения для особых случаев.


ЕМ>Откуда такое пристрастие, кроме как от лени? Вроде как сколько-нибудь массовых процессоров, где беззнаковые целые поддерживались бы ограниченно, не существует. Есть в этом хоть какое-то рациональное зерно?


Откуда эта лютая любовь к без знаковым целым? От жадности? Зачем использовать без знаковое целое где можно использовть обычный int или very long long. Только ради экономии 1-го бита? В большнистве случаев целые числа используются с запасом по разрядной сетке иногда с эпичемким запасом. В редких случаях бывает удобно использовать беззнаковые числа, например при сравнении знаковых (unsigned)(x-x0) < (unsigned)width вместо двух сравнений достаточно 1-го и при битовых сдвигах. В остальных случаях знаковых более чем достаточно. Более того минимальное отрицательное число можно использовать как признак отсутствия значения. if (x && x==-x) return novalue();

ps: меня больше огорчает всеобщее пристрастие к условию выхода из цикла for(size_t i=0;i!=end;++i){} где исключается одна точка, вместо for(size_t i=0;i<end;++i){} где запрещаются все недопустимые значения.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.