[java] Кодирование данных
поясни, что ты понимаешь под кодером?
поясни, что ты понимаешь под кодером?что-нибудь, что вручную обрабатывает поток данных и кодирует их в другой поток. Смысл - чтобы всё было компактно и занимало меньше место. Например, кодирование с помощью арифметического сжатия.
что-нибудьв гугле забанили? почему думаешь, что посетители форума тебе быстрее помогут, нежели гугл?
Самый простой способ - это пихать свое число в бОльший тип (например если хочешь unsigned int - бери long и как все сделал, отрезать по маске и кастить обратно в инт.
в гугле забанили? почему думаешь, что посетители форума тебе быстрее помогут, нежели гугл?гугл больше показывает флеймов на тему "вы не должны хотеть unsigned int" чем ответов
плюс здесь гарантировано есть студенты (бывшие) ватолинского спецкурса, вдруг кто из них пробовал яву
Самый простой способ - это пихать свое число в бОльший тип (например если хочешь unsigned int - бери long и как все сделал, отрезать по маске и кастить обратно в инт.сказывается инерция мышления. Мне это даже в голову не пришло
например sun.nio.cs.MS1251$Encoder
в jdk вообще все эти твои т.н. кодеры на нативе написаны.ну я так и думал. скорость важна, а других инструментов в яве нет, кроме натива. Я так полагаю, что разработчики явы инт считали исключительно чем-то вроде хранителя счётчика или единиц товара на складе. Int как данные не рассматривался при составлении ТЗ.
Почему это педерастия: потому что uint32 это математический объект "элемент кольца вычетов по модулю 2^32", а вовсе не "неотрицательное число". В своей истинной роли он удобен для всякой побитовой арифметики, да, а вот к использованию в роли "неотрицательного числа" он категорически непригоден ибо не кидает эксепшена при underflow (что противоречило бы наоборот истинной роли а даже если б и кидал то этого было бы недостаточно для вменяемого использования в цикле от 10 до 0, например.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
можно было их во framework добавить, но не делать кратких имен в языке, а оставить имена вида: bla.bla.SpecialUnsignedInt32
Почему это педерастия: потому что uint32 это математический объект "элемент кольца вычетов по модулю 2^32", а вовсе не "неотрицательное число"есть какие-то более развернутые аргументы на этот счет? я в C++ коде использую uint именно для неотрицательных чисел и не считаю это неправильным
по-моему тоже ничего криминального.
есть какие-то более развернутые аргументы на этот счет? я в C++ коде использую uint именно для неотрицательных чисел и не считаю это неправильнымпример:
ну вот есть у тебя условие (a < b + c) и пусть по смыслу все числа неотрицательные (длины там или количества) и вот ты для наглядности переписываешь это условие эквивалентным образом (a - b < c).
И тут сюрприз! если переменные uint'ы - то это преобразование будет уже не эквивалентным (при например a=0 b=1 c=0).
есть какие-то более развернутые аргументы на этот счет? я в C++ коде использую uint именно для неотрицательных чисел и не считаю это неправильнымпри использовании uint уменьшается запас прочности кода и иногда нарушается принцип наименьшего удивления ( http://en.wikipedia.org/wiki/Principle_of_least_astonishment )
например, следующий код никогда не завершается при a = 0, хотя это и не очевидно при беглом взгляде
uint a = GetMinBorder;
for (uint i = 10; i >= a; --i)
{
..
}
например, следующий код никогда не завершается при a = 0, хотя это и не очевидно при беглом взглядепри a = 0 выполняется инвариант unsigned int: x >= 0. Так что никакого удивления нет, зря ты его сюда приплёл. Проблема не в том, что unsigned не очевиден, а в том что особо одарённые программисты не могут одновременно запомнить что такое signed и unsigned типы и забывают какая переменная какому типу принадлежит.
при a = 0 выполняется инвариант unsigned int: x >= 0для переменной цикла этот инвариант не выполняется
для переменной цикла этот инвариант не выполняетсяэто как? любой uint >= 0.
это как? любой uint >= 0.uint да, а переменная цикла, которая пробегает по убывающей последовательности uint-ов имеет уже инвариант >= -1, что выходит за uint.
Для избежания подобных бед восприятия я бы не отменял бы uint, а сделал бы так, чтобы константы типа uint 12u, 0u, приводились бы к signed int только явно и наоборот, 0 и 12 к uint тоже надо было бы приводить явно
Проблема unsigned не в кольце, а в том, что, как правило, вычисления делаются возле нижней границы его диапазона, и легко промахнуться. Если считать в знаковых интах рядом с их границей - будет еще хуже, там сразу UB.
Ну и еще такой момент что unsigned при случае промоутится в int, а не наоборот. Поэтому, чтобы использовать верхнюю половину диапазона, нужно аккуратно писать код, и компиляторы обычно предупреждают о смешанных сравнениях.
При этом в полном соответствии с типом, как ты метко заметил кольца вычетов по модулю 2^32, 0 - 1 = 2^32-1это всё отлично, но только опять же никоим образом не совпадает с семантикой переменной цикла. Переменная цикла требует непрерывных целых чисел, без всяких вычетов.
Ну и еще такой момент что unsigned при случае промоутится в int, а не наоборот.только ровно наоборот - signed промоутится в unsigned, и именно поэтому и warning.
unsigned при случае промоутится в long но только на платформах где sizeof(long) > sizeof(unsigned т.е. только в 64-битной режиме на всех юниксах/линуксах. Для 64-бит на винде и для любых 32-бит — см. выше.
ну это просто в C плохой for
ну это просто в C плохой forто ли дело в лиспе
ну это просто в C плохой forпокажи, пожалуйста, правильный for, для которого не будет данной проблемы.
ну паскалевский
ну паскалевскийесли задавать через downto, то да.
но for это лишь частный пример глобальной проблемы:
значительное кол-во алгоритмов работающих с числовым диапазоном [a;b] могут внутри себя переходит к диапазону [a - delta; b + delta], что не составляет проблемы, пока диапазон [a;b] с обоих сторон много меньше, чем весь диапазон значений используемого типа данных,
но если работа происходит на границе диапазона, то это требует аудита реализации всех используемых алгоритмов - не расширяют ли они используемый диапазон для внутренней работы или при работе с вырожденными случаями.
При использовании uint-а работа почти всегда происходит на границе поддерживаемого диапазона, что делает обязательным такой аудит. Но на практике такой аудит редко проводится, что и приводит к снижению устойчивости кода к ошибкам.
можно запретить вычитания и декремент для unsigned например
можно запретить вычитания и декремент для unsigned напримери зачем тогда такой урезанный uint? всего лишь ради увеличения диапазона в два раза при работе с циклами?
для сдвигов, деления с остатком, битовых операций
не уверен, что этого будет достаточно для решения задач, связанных с обработкой байт.
покажи, пожалуйста, правильный for, для которого не будет данной проблемы.Любой foreach + правильные генераторы. Кстати да, индексные циклы - зло.
uint нужен, чтобы не писать каждый раз проверку на >= 0 для заведомо неотрицательных величин вроде размера или индекса.
uint нужен, чтобы не писать каждый раз проверку на >= 0 для заведомо неотрицательных величин вроде размера или индекса.фигня же
когда загружаешь эту величину в переменную, надо проверять всё равно
Ну да, вместо этого пишешь проверку на <size.
когда загружаешь эту величину в переменную, надо проверять всё равноНе понял, что ты имеешь ввиду. Можешь пример привести?
то нужно самому проверить, что get_some_value возвращает неотрицательное значение, иначе получится какая-то фигня, и так при любом присваивании
то нужно самому проверить, что get_some_value возвращает неотрицательное значение, иначе получится какая-то фигня, и так при любом присваиванииЕсли get_some_value уже unsigned - то не нужно.
Если нет, то проверку придётся делать что в случае с signed, что с unsigned. Но в последним случаем в некоторых языках достаточно будет воспользоваться checked преобразованием.
Если get_some_value уже unsigned - то не нужно.ну оно каким-то образом получилось внутри функции - тогда проверка должна была быть там
то проверку придётся делать что в случае с signed, что с unsigned.ну я про то и говорю, что никакой особой беззнаковой магии нет: если например вычисляешь разность двух величин, результат может быть отрицательным - такова жизнь
особо одарённые программисты не могут одновременно запомнить что такое signed и unsigned типы и забывают какая переменная какому типу принадлежитвот суки а
что еще забывают?
если например вычисляешь разность двух величин, результат может быть отрицательным - такова жизньа ты вычисляй разность по модулю
что еще забывают?имхо, они вообще ничего не помнят. Стандартный ответ: фиг его знает, посмотри в коде.
ну вот и я про то же
Оставить комментарий
yroslavasako
На сях удобно писать кодеры с использованием unsigned int, сдвигов, целочисленного деления с остатком. Как это всё пишется на java? Там нету unsigned данных, для signed - проблемы с неправильным дивом, который для x > 0 делает floor, для x < 0 - ceiling. Может у кого есть пример быстрого (не побитового) арифметического кодера под яву?