Есть ли способ кодировать целочисленные значения, превышающие 32 бита, с помощью bs-json?
Я использовал строки для представления декодированных целых чисел JSON размером более 32 бит. Кажется,
string_of_int
способен работать с большими целочисленными входами. Итак, декодер, записанный (в пространстве имен Json.Decode):
id: json |> field("id", int) |> string_of_int, /* 'id' is string */
успешно работает с целыми числами не менее 37 бит.
С другой стороны, кодирование доставляет мне хлопоты. Удаленный сервер не принимает строковое представление и ожидает int64. Можно ли сделать
bs-json
поддержать
int64
тип? Я надеялся, что что-то вроде этого заработает:
type myData = { id: int64 };
let encodeMyData = (data:myData) => Json.Encode.(object_([("id", int64(myData.id)]))
Необходимость использовать собственный кодировщик не так страшна, как декодер, но ... я бы предпочел не делать этого.
1 ответ
Вы не говорите точно, какая у вас проблема с кодировкой. Кодировщик буквально ничего не делает, кроме изменения типа, веря, что значение действительно действительное. Поэтому я предполагаю, что именно операция вызывает проблемы. Но возникает вопрос: если вы можете успешно декодировать его как, то почему вы затем конвертируете его в
string
?
Основная проблема здесь в том, что в JavaScript нет 64-битных целых чисел. Максимально безопасное число - 53 - 1. JavaScript фактически не имеет целые чисел, то лишь с, который может представлять собой определенный диапазон целых чисел, но не может эффективно выполнять целочисленную арифметику , если они не преобразуются либо 32-бит или 64-битные файлы. И поэтому по какой-то причине, вероятно, согласованной обработки переполнения, в спецификации EcmaScript было решено, что двоичные побитовые операции должны работать с 32-битными целыми числами. Таким образом, это открыло возможность для внутреннего 32-битного представления, нотации для создания 32-битных целых чисел и возможность оптимизированной целочисленной арифметики над ними.
Итак, на ваш вопрос:
Было бы "безопасно" просто добавить внешний int64: int64 -> Js.Json.t = "%identity" в файлы кодировщика?
Нет, потому что в JavaScript нет 64-битного целочисленного представления,
int64
значения представлены в виде массива из двух
Number
s Я полагаю, но это также внутренняя деталь реализации, которая может быть изменена. Просто бросаю это на
Js.Json.t
не даст ожидаемого результата.
Так что можете вы тогда ?
Я бы рекомендовал использовать. В большинстве случаев это будет вести себя точно так же, как числа JavaScript, предоставляя вам доступ ко всему его диапазону.
В качестве альтернативы вы можете использовать
<tcode id="4401361"></tcode>, который должен вести себя как
float
s за исключением деления, когда результат усекается до 32-битного целого числа.
Наконец, вы также можете реализовать свой собственный
int_of_string
создать
int
это технически выходит за пределы допустимого диапазона, если напрямую использовать пару облегченных функций JavaScript, хотя я бы не рекомендовал это делать:
let bad_int_of_string = str =>
str |> Js.Float.fromString |> Js.Math.floor_int;