2.8Kпросмотров
11 декабря 2024 г.
questionScore: 3.1K
Что не так с float'ом и спасет ли double? По каким таким причинам биржи не уважают floating-point numbers? Смотришь в документацию, а они в json'ах цену и количество лотов шлют не number type, а string type. Не {"price":36.12}, а {"price":"36.12"}. Они так делают, если: - практически: в их кодовой без используется какой-нибудь BigDecimal, который так сериализует числа. - теоретически: они не могут гарантировать отсутствие чисел, непредставимых в double типе (например, 9007199254740993.0), даже, если сейчас такого не видно на горизонте. Проблема не в «маленьком диапазоне» double, а в невозможности точной двоичной репрезентации десятичных дробей. - для некоторых полей такую гарантию они могут дать, и тогда они используют uint64 (сравни поля ts и v). - они заботятся о пользователе, вводя проблему в сознательную область (т.к. теперь просто as_float() в парсере не вызовешь) и снижая вероятность ошибки. - упрощают пользователю возможность прокинуть строку в свой кастомный парсер (не часть json либы). - оставляют себе микро-возможность вписать пустую строку, либо "Nan" или "Inf" (и такое бывало). С точки зрения спецификации json тип Number не ограничен в размере и точности, но на практике юзерские либы же как-то должны с этим работать, поэтому на эту особенность спеки положиться нельзя. Ладно, с биржами понятно. Допустим, прислали нам "amount":"36.12". В чем ваш trading engine будет это хранить? Это фундаментальный вопрос для торговой системы. Ни ужели точности double не хватит, ведь он может показывать числа от 2.22507e-308 до 1.79769e+308, что уже довольно дофига? Как будто бы может и хватить, но все же легко наступить на грабли: - Операции не ассоциативны: (a + b) + c может быть не равно a + (b + c). - Различные платформы могут давать различные результаты операций. - Ошибки округления накапливаются при последовательных математических операциях (см. 0.1 + 0.2). - Сравнивать два floating-point числа напрямую чревато. - Что-то еще наверянка забыл, дополните, плз. Практический пример: вы посылаете торговый ордер на quantity 0.3, вам приходит три сделки по 0.1. Вы их складываете, чтобы понять полностью ли заполнен ордер, и тут вы и приехали, ибо: (0.1 + 0.1 + 0.1) == 0.3 вычисляется в false Да, вы можете сравнить числа через epsilon (abs(a-b) < eps), но потенциально легко где-то забыть вызвать правильную функцию. Что тогда, вон из профессии? По итогу, используется либо double с дополнительными приседаниями (обвязками, проверками и т.п.), либо кастомный decimal тип (пример), либо изначально величины хранятся в самых мелких единицах (пример из Ethereum).
2.8K
просмотров
2605
символов
Нет
эмодзи
Нет
медиа

Другие посты @hft_dev

Все посты канала →
Что не так с float'ом и спасет ли double? По каким таким при — @hft_dev | PostSniper