netch80: (Default)
[personal profile] netch80
Подробный список известных вариантов хранения с плавающей точкой на всех известных архитектурах - просто доставляет разнообразием и хитрыми решениями.

Несмотря на это, всё равно придётся делать своё - потому что должно тривиально читаться в hex-дампе.

(И вообще автор жжот нипадецки - но оценить его могут только те, кто работал с битово-ассемблерными потрохами минимум двух заметно разных рахитектур...)

Date: 2011-06-25 08:23 am (UTC)
From: [identity profile] lionet.livejournal.com
ASN.1 to rescue.

Date: 2011-06-25 08:25 am (UTC)
From: [identity profile] netch80.livejournal.com
Его форматы по сравнению с моими планами крайне неэкономны (это я даже не учитываю цену разбора списка, сейчас это по сути простой TLV, а получится ХЗ что).

Date: 2011-06-25 09:00 am (UTC)
From: [identity profile] lionet.livejournal.com
Ну так TLV — это базовый формат ASN.1, можно и компактнее. Например, PER, компактнее которого формата придумать сложно.

Кроме того, даже в TLV плавающая точка в ASN.1 кодируется очень компактно. Например, кодирование нуля занимает ноль байт V (то есть, без учёта двух байта на T и V). Кодирование маленьких чисел тоже экономнее, чем больших.

Date: 2011-06-25 09:26 am (UTC)
From: [identity profile] netch80.livejournal.com
Мне нужно
1) фиксированный размер представления (4 байта)
2) фиксированный формат
3) отсутствие лишних указателей типа "а тут у нас float"
4) чтобы легко воспринималось глазами в потоке - например "это +20"

Date: 2011-06-25 09:49 am (UTC)
From: [identity profile] lionet.livejournal.com
В четыре байта много не засунешь, чтобы удовлетворяло всем условиям. Либо float, но тогда там шум будет, а не пункт 4, либо текстовое представление (аналог NR3), с фиксированным количеством знаков до и после точки. А у такого формата будет фиксированная точка и низкое разрешение.

По-моему, пункты 1 и 4 противоречат друг другу.

Date: 2011-06-25 12:11 pm (UTC)
From: [identity profile] netch80.livejournal.com
Что получилось:
- по смещению 0 - порядок, несмещённый (но см. ниже про позицию точки), в 2-complement, с основанием 16. То есть 0xFE значит "мантиссу разделить на 256", 0x01 - "мантиссу умножить на 16". Значение 0x80 выделено для спецсигналов типа "не смогли снять" (sNaN), "этого датчика вообще нет" (qNaN) и так далее.
- по смещениям 1-3 - мантисса, целое в 2-complement, точка в самом конце. Никакой нормализованности не требуется, агенты сбора данных не будут этим заниматься.
Например:
00 00 00 7F - значение +127
00 FF FF 81 - значение -127
FE 00 01 1C - значение 1.109 (такие идут, например, для VCore - они снимаются в сыром виде в 1/64 вольта, так что агент домножит на 4 и уложит в мантиссу, а порядок поставит в 0xFE)
80 01 00 00 - не удалось снять (signaling NaN, subvalue = 0)

и никакого противоречия.

На всякий случай уточню, что "вижу 7F и понимаю, что это 127" нам таки доступно. :)

Date: 2011-06-25 07:21 pm (UTC)
From: [identity profile] lionet.livejournal.com
Поздравляю, ты придумал float32, который сложнее читать из-за 2-complement :)

На самом деле, основание 16 даёт больший range, но зато уменьшает precision с номинальных 23 бит до, в худшем случае, 19 бит. То есть, точность будет плавать где-то в районе 0.0002% (ошибка 0.0000019)
Не то чтобы это совсем плохо, но в float32:

1) знак виден сразу, ибо один бит на это выделен отдельно, а не сделана замесь в 2-complement.
2) отрицательные и положительные числа имеют одинаковый диапазон
3) отрицательные числа не сложнее воспринимать, чем положительные
5) мантисса имеет диапазон 2^-127..2^127, что исключительно прилично (подходит для всех измерений, кроме астрономических), а у тебя 16^-127..16^128, что непонятно зачем нужно. Для примера, 16^128 это "13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096", что совершенно дико и никогда не понадобиться вообще никому в мире в ближайший гугол лет. Лучше бы ты бит знака сделал в нулевом байте, чуть прижав диапазон экспоненты.

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

Короче, можно лучше, и float32 — это почти идеальная вещь, только знак и экспоненту местами поменять: 8:1:23. Ну или в твоём формате, раз ты не гнушаешься прыжками точности мантиссы при переходе между разными значениями экспоненты, можно поприжать размер экспоненты и вынести знак и флаги в отдельные пару (четвёрку?) бит: 1:3:4:24 (знак-флаги-экспонента для b=16, мантисса).

Date: 2011-06-25 07:27 pm (UTC)
From: [identity profile] netch80.livejournal.com
> Поздравляю, ты придумал float32, который сложнее читать из-за 2-complement :)

В моём случае таки проще читать. Можешь считать местной спецификой;)

Про основание порядка - ok, согласен, сделаем двоичным.

float32 (точнее, binary32 имени IEEE754) мне не нравится именно принудительной нормализацией к верхним значениям.

Date: 2011-06-25 07:51 pm (UTC)
From: [identity profile] lionet.livejournal.com
Ну и то хлеб.

Кстати, нормализация — это процесс, никто же не заставляет его делать тебе. Просто формат у него можно взять и всё.

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

Date: 2011-06-25 08:00 pm (UTC)
From: [identity profile] netch80.livejournal.com
> Кстати, нормализация — это процесс, никто же не заставляет его делать тебе.

Заставляет, если как в IEEE754 при biased_exponent != 0 старший бит мантиссы всегда 1 и скрыт.

Date: 2011-06-25 08:12 pm (UTC)
From: [identity profile] lionet.livejournal.com
А, точно.

Date: 2011-06-25 09:18 am (UTC)
ext_605364: geg MOPO4 (Default)
From: [identity profile] gegmopo4.livejournal.com
О, добавил в закладки.

А зачем своё? Для hex-дампа есть %a. ;)

Date: 2011-06-25 09:24 am (UTC)
From: [identity profile] netch80.livejournal.com
В hex-дампе пакета надо легко глазами прочитать, что тут передаётся +29 или, например, 0 целых 197 256-ых.
При передаче, например, в IEEE754 такой лёгкости нет.

Date: 2011-06-25 09:50 am (UTC)
From: [identity profile] lionet.livejournal.com
В ASN.1 есть формат NR3, там вообще в тексте будет "0.123"

Date: 2011-06-25 09:09 pm (UTC)
ext_605364: geg MOPO4 (Default)
From: [identity profile] gegmopo4.livejournal.com
Ну, это свойство плавающей двоичной точки — человеконечитаемость. Если нормализировано — то сдвигается чёрте куда, если не нормализировано — то неоднозначно.

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

Date: 2011-06-25 06:27 pm (UTC)
From: [identity profile] dimich-dmb.livejournal.com
Познавательная подборка, tnx. А какую точность требуется обеспечить? Имхо, при фиксированном размере придется искать золотую серенину между точностью и читаемостью дампа. В определенных случаях было бы эффективно хранить значение в виде дроби целых плюс экспонента, например.

Date: 2011-06-25 11:32 pm (UTC)
From: [identity profile] lionet.livejournal.com
Кстати, насчёт архитектур, ASN.1 и интероперабельности:

http://erlang.org/pipermail/erlang-bugs/2011-June/002486.html

Какое же всё-таки это дерьмо, этот ваш ASN.1...

Date: 2011-06-26 07:09 am (UTC)
From: [identity profile] netch80.livejournal.com
Ну зачем же так обобщать. Просто какой-то частный случай, corner case, который толком не проработали. Вообще, если ты заметил, Erlang только пару лет как начал выходить на широкий простор, а до того использовался узкой группой людей в специфических интересах, и такие тёмные места во всех углах в нём сотнями и тысячами...

Profile

netch80: (Default)
netch80

January 2026

S M T W T F S
    1 23
45678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 2nd, 2026 06:51 pm
Powered by Dreamwidth Studios