Re[4]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 11:16
Оценка:
Здравствуйте, netch80, Вы писали:

N>С этим оператором для N-битного числа ты не сможешь сделать, чтобы первая итерация была 2**N-1 (например, в 32-битке нельзя сделать, чтобы первая итерация была для i == 0xFFFF_FFFF)


Лучше покажи реализацию на int32_t
Re[6]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 11:26
Оценка:
Здравствуйте, T4r4sB, Вы писали:

EP>>while(n--) — стандартная идиома, встречается повсеместно.

TB>Да, но тогда и надо писать цикл вайлом, а не фором.

Ну while в таких случаях обычно используют когда n пришло в виде аргумента, а for когда нужна инициализация на месте.
В чём разница-то? Почему считаешь что одно комильфо, а другое нет?

TB>И это всё равно не отменяет того факта, что такое решение — костыль.


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

EP>>Следуя таким же рассуждениям, можно прийти к "на знаковых нормально корень из отрицательных не извлечь, надо переходить к гауссовым числам"

TB>Дык и правда не извлечь. Но это редко когда надо.

Итерация вниз, мало того что редко встречается, так ещё и элементарно реализуется на беззнаковых.
И даже если бы не было нормальной реализации, то это не было бы основанием использовать знаковые повсеместно, ибо и у знаковых и у беззнаковых есть свои плюсы и минусы
Re[3]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 11:33
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Не не не, Дэвид Блэйн, меня ты не проведёшь.

EP>Там где проявляется закольцованность у безнаковых, у знаковых вообще случается undefined behaviour (речь же о C++?). Причём для индексов случается чаще, в силу меньшего положительного диапазона.

Хм, это таки надо постараться переполнить переменную индекса в сторону за его максимум.
Как нужно писать, чтобы это сделать?

EP>В одном случае имеем чёткую модель кольца, а в другом даже магмы нет, ибо операции не замкнуты


Модель кольца можно сделать через -fwrapv или overflow builtins. Но я бы предпочёл исключения по умолчанию.
The God is real, unless declared integer.
Re[5]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 11:36
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


N>>С этим оператором для N-битного числа ты не сможешь сделать, чтобы первая итерация была 2**N-1 (например, в 32-битке нельзя сделать, чтобы первая итерация была для i == 0xFFFF_FFFF)


EP>Лучше покажи реализацию на int32_t


Я и не претендовал — я показал недостаток предложенной схемы, который надо учитывать при подобном подходе.
В общем же случае надо, повторю в 5й раз, сначала разобраться с диапазонами и методами невыхода за них, и только после этого думать, в какой же тип оно уляжется.
The God is real, unless declared integer.
Re[9]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 11:44
Оценка: +1
Здравствуйте, vopl, Вы писали:

V>1. целые int32_t не являются подмножеством математических целых, так как они закольцованы


Они не закольцованы, а за-ub'ешены.

EDIT: здесь был ошибочный пример ub, новый пример вот тут
Автор: Evgeny.Panasyuk
Дата: 09.05.20
Отредактировано 09.05.2020 15:10 Evgeny.Panasyuk . Предыдущая версия . Еще …
Отредактировано 09.05.2020 14:25 Evgeny.Panasyuk . Предыдущая версия .
Отредактировано 09.05.2020 14:24 Evgeny.Panasyuk . Предыдущая версия .
Отредактировано 09.05.2020 11:46 Evgeny.Panasyuk . Предыдущая версия .
Отредактировано 09.05.2020 11:45 Evgeny.Panasyuk . Предыдущая версия .
Re[7]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 09.05.20 11:52
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>В чём разница-то? Почему считаешь что одно комильфо, а другое нет?


Потому что это не является ожидаемым использование фора.

EP>Стандартная идиома, с вполне определённым поведением. Нужно знать хотя бы потому что встречается во многих проектах.


А почему на знаковых не надо какие-то идиомы сочинять?

EP>Итерация вниз, мало того что редко встречается, так ещё и элементарно реализуется на беззнаковых.


Элементарно костылится, ты хотел сказать.

EP>И даже если бы не было нормальной реализации, то это не было бы основанием использовать знаковые повсеместно


Знаковые не нужны пр битовых операциях, а ещё где?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[4]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 12:00
Оценка: :)
Здравствуйте, netch80, Вы писали:

EP>>Там где проявляется закольцованность у безнаковых, у знаковых вообще случается undefined behaviour (речь же о C++?). Причём для индексов случается чаще, в силу меньшего положительного диапазона.

N>Хм, это таки надо постараться переполнить переменную индекса в сторону за его максимум.
N>Как нужно писать, чтобы это сделать?

Например индекс int8_t итерируется по массиву в 200 элементов

EP>>В одном случае имеем чёткую модель кольца, а в другом даже магмы нет, ибо операции не замкнуты

N>Модель кольца можно сделать через -fwrapv

Я выше примерчик привёл
Автор: Evgeny.Panasyuk
Дата: 09.05.20
. Найди комбинацию флагов печатающую числа, а потом не забудь всем пользователям кода сказать чтобы использовали такие же флажки, и ещё если вдруг угораздит перейти на другой компилятор, чтобы нашли эквивалент, так как автор беззнаковые не хотел использовать
Re: Откуда эта лютая любовь к знаковым целым?
От: Michael7 Россия  
Дата: 09.05.20 12:05
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

Много чего написали в этом обсуждении, но никто кажется не вспомнил про KISS принцип, хотя и неявно сформулировали.

ЕМ>Откуда такое пристрастие, кроме как от лени?


Разумная лень — двигатель прогресса вообще-то Если чего-то можно не делать — его не следует делать.
Соответственно, если нет каких-то причин использовать беззнаковый тип, проще использовать знаковый и меньше думать о том может это привести к ошибке или нет.
Re[4]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 12:40
Оценка:
Здравствуйте, netch80, Вы писали:

H>>>Во-вторых, иногда нужно не-валидное значение чего-то, что по смыслу неотрицательно. И для этого я лично использую «-1». И если переменная равна ему, то значит значение невалидное. Такая штука с unsigned не проканает, если не вводить всякие magic digits конечно.

PJ>>std::optional<uint>
N>И терять 4-8 байт вместо одного бита ;[

По корректности optional будет лучше чем int/unsigned с рукопашными сигнальными значениями и необходимостью проверок по всему коду.
Но да, у std::optional большие накладные расходы — для таких случаев легко пишется свой optional не уступающий рукопашному варианту по скорости/размеру.
Re[8]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 12:48
Оценка:
Здравствуйте, T4r4sB, Вы писали:

EP>>В чём разница-то? Почему считаешь что одно комильфо, а другое нет?

TB>Потому что это не является ожидаемым использование фора.

То же самое, только в профиль: for(;n--; ) vs while(n--)

EP>>Стандартная идиома, с вполне определённым поведением. Нужно знать хотя бы потому что встречается во многих проектах.

TB>А почему на знаковых не надо какие-то идиомы сочинять?

Это идиома и на знаковых отлично работает: while(n--). Покажи свой вариант, сравним
Re[9]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 09.05.20 14:05
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>То же самое, только в профиль: for(;n--; ) vs while(n--)


В таких случаях for неуместен.

EP>Это идиома и на знаковых отлично работает: while(n--).


Я это отрицал что ли? Я говорю, что нормальный фор на беззнаковых без костылей не пишется.

EP>Покажи свой вариант, сравним


for (int i=a.size()-1; i>=0; --i);

просто и в лоб, два пограничных значения и итерация
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[10]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 14:16
Оценка: 2 (1) +2 :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

V>>1. целые int32_t не являются подмножеством математических целых, так как они закольцованы


EP>Они не закольцованы, а за-ub'ешены:

EP> for(int i=0; i>0; ++i) {
EP> cout << i << " ";
EP> }

Мнэээ...
Подготовка цикла: ставим i = 0.
Проверка на входе в цикл: i > 0 — не выполняется. Немедленно завершаем цикл.

Где UB? Код корректный для любого компилятора, ничего не делает. И, кстати, для unsigned был бы результат точно такой же — честные 0 итераций цикла.

Вы что доказать-то хотели?
The God is real, unless declared integer.
Re[5]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 14:16
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Там где проявляется закольцованность у безнаковых, у знаковых вообще случается undefined behaviour (речь же о C++?). Причём для индексов случается чаще, в силу меньшего положительного диапазона.

N>>Хм, это таки надо постараться переполнить переменную индекса в сторону за его максимум.
N>>Как нужно писать, чтобы это сделать?

EP>Например индекс int8_t итерируется по массиву в 200 элементов


Ну и зачем кому-то потребовалось сужать такой индекс по сравнению с умолчательным int?

EP>>>В одном случае имеем чёткую модель кольца, а в другом даже магмы нет, ибо операции не замкнуты

N>>Модель кольца можно сделать через -fwrapv
EP>Я выше примерчик привёл
Автор: Evgeny.Panasyuk
Дата: 09.05.20
.


Видел. Честные 0 итераций независимо от знаковости. Исправьте пример или не смешите мои тапочки (tm).
The God is real, unless declared integer.
Re[5]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 14:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

H>>>>Во-вторых, иногда нужно не-валидное значение чего-то, что по смыслу неотрицательно. И для этого я лично использую «-1». И если переменная равна ему, то значит значение невалидное. Такая штука с unsigned не проканает, если не вводить всякие magic digits конечно.

PJ>>>std::optional<uint>
N>>И терять 4-8 байт вместо одного бита ;[
EP>По корректности optional будет лучше чем int/unsigned с рукопашными сигнальными значениями и необходимостью проверок по всему коду.

Ну а почему сразу и рукопашными? Вполне можно сделать обёртку для типа, который принимает значения от 0 до INT_MAX, а отсутствие значения передаёт как -1.

Кстати, это ровно соответствует интерфейсу Linux syscalls (только там выделено в спецслучаи от -4096 до -1, как errno с минусом).

EP>Но да, у std::optional большие накладные расходы — для таких случаев легко пишется свой optional не уступающий рукопашному варианту по скорости/размеру.


Вот чтобы получить не уступающий по размеру — как раз и нужно урезать диапазон значений.
The God is real, unless declared integer.
Re[10]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 14:21
Оценка:
Здравствуйте, T4r4sB, Вы писали:

EP>>Покажи свой вариант, сравним

TB>
TB>for (int i=a.size()-1; i>=0; --i);
TB>

TB>просто и в лоб, два пограничных значения и итерация

Ну то есть выбирая между:
for (int i=n-1; i>=0; --i)
и
while(n--)

Ты всё ещё предпочтёшь воротить нос от стандартной и лаконичной идиомы, в пользу более сложного выражения, в котором проще допустить ошибку, которое работает только со знаковыми, из-за субъективной "костыльности" стандартной идиомы?
Re[11]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 14:29
Оценка:
Здравствуйте, netch80, Вы писали:

N>Подготовка цикла: ставим i = 0.

N>Проверка на входе в цикл: i > 0 — не выполняется. Немедленно завершаем цикл.

Точно, ошибка.

N>Вы что доказать-то хотели?


Думал получилось триггернуть UB вроде этого
Автор: Evgeny.Panasyuk
Дата: 30.10.15
.
Re[6]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 14:35
Оценка:
Здравствуйте, netch80, Вы писали:

EP>>По корректности optional будет лучше чем int/unsigned с рукопашными сигнальными значениями и необходимостью проверок по всему коду.

N>Ну а почему сразу и рукопашными? Вполне можно сделать обёртку для типа, который принимает значения от 0 до INT_MAX, а отсутствие значения передаёт как -1.

Я ровно это и имею в виду. Нужно не сравнивать вручную, а использовать optional-like обёртку, которая не будет уступать по скорости/размеру ручному варианту, и одинаково хорошо работать как со знаковыми, так и беззнаковыми.
Re[12]: Откуда эта лютая любовь к знаковым целым?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 09.05.20 15:01
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

N>>Подготовка цикла: ставим i = 0.

N>>Проверка на входе в цикл: i > 0 — не выполняется. Немедленно завершаем цикл.
EP>Точно, ошибка.
N>>Вы что доказать-то хотели?
EP>Думал получилось триггернуть UB вроде этого
Автор: Evgeny.Panasyuk
Дата: 30.10.15
.


Я попробовал заменить на i=1 в начале цикла. GCC (5), Clang (6) — UdB не триггерится. Не опознаёт оно переполнение.
Видимо, надо ему упростить задачу
The God is real, unless declared integer.
Re[6]: Откуда эта лютая любовь к знаковым целым?
От: Evgeny.Panasyuk Россия  
Дата: 09.05.20 15:04
Оценка: 1 (1) +1
Здравствуйте, netch80, Вы писали:

EP>>Я выше примерчик привёл
Автор: Evgeny.Panasyuk
Дата: 09.05.20
.

N>Видел. Честные 0 итераций независимо от знаковости. Исправьте пример или не смешите мои тапочки (tm).

#include <iostream>
#include <climits>
using namespace std;

int main()
{
    for(int i=INT_MAX-2; i>=0; ++i) {
        cout << i << " ";
    }
}
Вывод:
g++ -std=c++17 -O3 -Wall -pedantic main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:7:5: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
    7 |     for(int i=INT_MAX-2; i>=0; ++i) {
      |     ^~~
main.cpp:7:27: note: within this loop
    7 |     for(int i=INT_MAX-2; i>=0; ++i) {
      |                          ~^~~
2147483645 2147483646 2147483647 -2147483648 -2147483647 ... infinite loop

https://godbolt.org/z/3WkoMN
.L2:
        mov     esi, ebx
        mov     edi, OFFSET FLAT:_ZSt4cout
        add     ebx, 1
        call    std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
        mov     edx, 1
        mov     esi, OFFSET FLAT:.LC0
        mov     rdi, rax
        call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
        jmp     .L2

Таки закольцевался int, правда jmp'ом
Re[11]: Откуда эта лютая любовь к знаковым целым?
От: T4r4sB Россия  
Дата: 09.05.20 15:33
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ты всё ещё предпочтёшь воротить нос от стандартной и лаконичной идиомы, в пользу более сложного выражения, в котором проще допустить ошибку, которое работает только со знаковыми, из-за субъективной "костыльности" стандартной идиомы?


"Работает только со знаковыми" для меня не недостаток, потому что я отказался от шизы сувать беззнаковые в какую-то переменную лишь потому, что она по смысле не может быть отрицательной, взамен получая грабли на преобразованиях и корректности промежуточных результатов.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.