LINUX.ORG.RU
ФорумTalks

Система счисления с основанием 10000.

 ,


0

1

Ковыряю тут сорцы постгреса, и нарвался на реализацию типа numeric (он же decimal). Сабж, каждая цифра хранится в int16. По здравому размышлению – логично: делать арифметику сразу на группах по 4 цифры эффективнее, чем на каждой десятичной цифре отдельно.

★★★★★

привет

рекомендую поковырять различные файловые форматы бинарных файлов, jpeg, png, gif, flv и так далее. они не просто лежат в открытом доступе, они на некоторых сайтах описаны таким простым языком, что ребёнок разберётся.

найдешь много интересных решений, когда один байт это число от 0 до 255, и используя различные вариации записи этих чисел — последовательность байт — тебе надо получить, например, число 31337.

вот формат PNG. чтобы определить, что это PNG, мы должны найти следующую последовательность байт: 137 80 78 71 13 10 26 10

затем мы ищем вот такую последовательность: 73 72 68 82 — отсюда начинается отсчёт следующей последовательности байт, содержащий в себе ширину и высоту PNG картинки.

и сразу после 73 72 68 82 мы берём 4 байта.

каждый байт в отдельности мы преобразуем из DEC в HEX, записываем рядом друг с другом как строку, то есть получаем вроде «ffffffff» из 4 байт. и затем вот это полученное число в HEX мы уже целиком и полностью преобразуем обратно в DEC. таким образом получая ширину картинки в пикселях.

тоже самое проделываем со следующими 4 байтами после ширины — это будет высота картинки.

из твоего треда я понял, что именно об этом ты и говоришь, говоря про группы из 4х цифр, последовательность 4х байт, каждый от 0 до 255 по аски таблице.

ну так вот, это далеко не ново и используется повсеместно. просто пока ты с этим не столкнёшься, кажется «вау-решением».

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

вот даже скрипт для mIRC сохранился на просторах интернетов: http://hawkee.com/scripts/12828336/

alias urlinf.gif {
  if ($hget(urlinf.sockets,$1,$+(&,$1)) = 0) return
  var %offset = $bfind($+(&,$1),1,13 10 13 10) + 4
  if ($prop == dimensions) {
    if ($bfind($+(&,$1),1,13 10 13 10 71 73 70 56 57 97)) return $v1
    if ($bfind($+(&,$1),1,13 10 13 10 71 73 70 56 55 97)) return $v1
  }
  if ($prop == width) return $base($+($base($bvar($+(&,$1),$calc(%offset + 7),1),10,16,2),$base($bvar($+(&,$1),$calc(%offset + 6),1),10,16,2)),16,10)
  if ($prop == height) return $base($+($base($bvar($+(&,$1),$calc(%offset + 9),1),10,16,2),$base($bvar($+(&,$1),$calc(%offset + 8),1),10,16,2)),16,10)
  return $bfind($+(&,$1),1,13 10 13 10 71 73 70)
}
Spoofing ★★★★★
()
Ответ на: комментарий от Spoofing

привет

рекомендую поковырять различные файловые форматы бинарных файлов, jpeg, png, gif, flv и так далее. они не просто лежат в открытом доступе, они на некоторых сайтах описаны таким простым языком, что ребёнок разберётся.

найдешь много интересных решений, когда один байт это число от 0 до 255, и используя различные вариации записи этих чисел — последовательность байт — тебе надо получить, например, число 31337.

вот формат PNG. чтобы определить, что это PNG, мы должны найти следующую последовательность байт: 137 80 78 71 13 10 26 10

затем мы ищем вот такую последовательность: 73 72 68 82 — отсюда начинается отсчёт следующей последовательности байт, содержащий в себе ширину и высоту PNG картинки.

и сразу после 73 72 68 82 мы берём 4 байта.

каждый байт в отдельности мы преобразуем из DEC в HEX, записываем рядом друг с другом как строку, то есть получаем вроде «ffffffff» из 4 байт. и затем вот это полученное число в HEX мы уже целиком и полностью преобразуем обратно в DEC. таким образом получая ширину картинки в пикселях.

тоже самое проделываем со следующими 4 байтами после ширины — это будет высота картинки.

из твоего треда я понял, что именно об этом ты и говоришь, говоря про группы из 4х цифр, последовательность 4х байт, каждый от 0 до 255 по аски таблице.

ну так вот, это далеко не ново и используется повсеместно. просто пока ты с этим не столкнёшься, кажется «вау-решением».

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

вот даже скрипт для mIRC сохранился на просторах интернетов: http://hawkee.com/scripts/12828336/

alias urlinf.gif {
 if ($hget(urlinf.sockets,$1,$+(&,$1)) = 0) return
 var %offset = $bfind($+(&,$1),1,13 10 13 10) + 4
 if ($prop == dimensions) {
   if ($bfind($+(&,$1),1,13 10 13 10 71 73 70 56 57 97)) return $v1
   if ($bfind($+(&,$1),1,13 10 13 10 71 73 70 56 55 97)) return $v1
 }
 if ($prop == width) return $base($+($base($bvar($+(&,$1),$calc(%offset + 7),1),10,16,2),$base($bvar($+(&,$1),$calc(%offset + 6),1),10,16,2)),16,10)
 if ($prop == height) return $base($+($base($bvar($+(&,$1),$calc(%offset + 9),1),10,16,2),$base($bvar($+(&,$1),$calc(%offset + 8),1),10,16,2)),16,10)
 return $bfind($+(&,$1),1,13 10 13 10 71 73 70)
}

интересно. Спасибо

ubik
()

сомнительно, результат перемножения, например, 9999^2, уже придется хранить в инт32. Менять типы/выравнивание для промежуточных вычислений может оказаться дороже. Кроме того, не знаю, как именно, там реализована арифметика, но при хранении каждой цифры по отдельности то же перемножение красиво реализуется как запись произведения двух цифр-множителей в ячейки со сдвигом равным сумме сдвигов множителей относительно единичного разряда. Ну и суммирование всех таких произведений. Собственно, детей так и учат, в столбик. В твоей же системе придется отдельно мучаться с тем, где сейчас находится запятая и что с чем нужно складывать

Интереснее, зачем они использовали шорт, а не байт под каждую цифру, но, возможно, держали в уме потенциальное применение для 16-ричной арифметики и взяли шорт, чтобы влезло F*F.

bl00dy
()

Такое основание проще в реализации, а частности проще делается чтение из строки и запись в строку в десятичном представлении. Для эффективности конечно надо делать основание 2^64, но тогда будет геморрой со строками.

Reset ★★★★★
()
Ответ на: комментарий от Reset

Для эффективности конечно надо делать основание 2^64,

Гы, прям мои вчерашние мысли. :)

но тогда будет геморрой со строками.

Логично. :)

dimgel ★★★★★
() автор топика
Ответ на: комментарий от dimgel

А ещё вернее, не 64 а 32 бита, чтобы результат умножения влез в 64. Хотя в gcc и clang есть __int128.

dimgel ★★★★★
() автор топика
Ответ на: комментарий от dimgel

Чем больше тем лучше, но для решения задач на каком-нибудь spoj или codeforces миллиона хватит за глаза – все тесты пройдут :)

Reset ★★★★★
()

Нет, нелогично, потому что тебе так или иначе придётся конвертировать ввод-вывод из/в человеческой десятичной записи. А если нужно конвертировать, то проще конвертировать сразу в двоичную и длинную арифметику тоже сделать двоичной, чем изобретать очередной велосипед с пятиугольными колёсами.

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Над этим тоже думал. Соображение в пользу их решения есть такое: вполне возможно, что им приходится конвертировать эти числа в/из десятичные строки не сильно реже, чем делать арифметику. Например потому что рекомендуемый формат обмена данными с сервером – текстовый, т.к. двоичный требует знания серверных структур, которые могут ещё и меняться со временем.

UPD: Так что выбор 10000 был результатом компромисса, и возможно даже нагрузочного тестирования в реальных системах.

dimgel ★★★★★
() автор топика
Последнее исправление: dimgel (всего исправлений: 2)
Ответ на: комментарий от dimgel

приходится конвертировать эти числа в/из десятичные строки не сильно реже, чем делать арифметику

А то и чаще. Numeric нужен для хранения денег, а много ли enterprise-систем делают вычисления на стороне SQL? Ну, кроме синтетических отчётов.

dimgel ★★★★★
() автор топика

Нет не эффективнее. Но у numeric очень большая разрядность, поэтому выбора не было особо.

ahdenchik
()
Ответ на: комментарий от dimgel

Например потому что рекомендуемый формат обмена данными с сервером – текстовый

а много ли enterprise-систем делают вычисления на стороне SQL?

Проткните информационный пузырь

ahdenchik
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.