Почему числа с 17 и более цифрами автоматически превращаются в ДАЖЕ? - PullRequest
3 голосов
/ 23 февраля 2012

Я тестирую фото приложение для Facebook. Я получаю идентификаторы объектов из API Facebook, но я получил несколько неправильных, которые не имеют смысла - почему Facebook отправляет неправильные идентификаторы? Я немного исследовал и обнаружил, что числа с 17 и более цифрами автоматически превращаются в четные числа!

Например, скажем, идентификатор, который я должен получить от Facebook, - 12345678912345679. В отладчике я заметил, что Flash Player автоматически превращает его в 12345678912345678. И я даже пытался вручную установить его на нечетное число, но оно продолжает возвращаться к четному.

Есть ли способ остановить округление чисел в Flash Player? Кстати, переменная определена как Object, я так и получаю ее от Facebook.

1 Ответ

11 голосов
/ 23 февраля 2012

Это связано с реализацией типов данных:

  • int - это 32-разрядное число с равномерным распределением положительных и отрицательных значений, включая 0. Таким образом,максимальное значение

    (2^32 / 2 ) - 1 == 2,147,483,647.

  • uint также является 32-разрядным числом, но оно не имеет отрицательных значений.Таким образом, максимальное значение составляет

    2^32 - 1 == 4,294,967,295.

Когда вы используете числовое значение, превышающее максимальное значение int или uint, оно автоматическиприведение к Number. Из Adobe Doc :

Тип данных Number полезен, когда вам нужно использовать значения с плавающей запятой.Среда выполнения Flash обрабатывает типы данных int и uint более эффективно, чем Number, но Number полезна в ситуациях, когда требуемый диапазон значений превышает допустимый диапазон типов данных int и uint.Класс Number можно использовать для представления целочисленных значений, выходящих далеко за пределы допустимого диапазона типов данных int и uint.Тип данных Number может использовать до 53 битов для представления целочисленных значений по сравнению с 32 битами, доступными для int и uint.

53 бит имеют максимальное значение:

2^53 - 1 == 9,007,199,254,740,989 => 16 цифр

Таким образом, при использовании любого значения, превышающего это, применяются внутренние значения чисел с плавающей запятой.

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

Если у вас есть значение, превышающее максимально возможное целочисленное значение, которое может иметь число, то младший значащий бит (представляющий 0 и 1) обрезается, чтобы учесть более значимый бит (один, представляющий 2 ^ 54), чтобы существовать => следовательно, вы теряете нечетные числа.

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

Кстати, если бы у вас было значение больше 2^54-(1+2), ваши числа были бы округлены вниздо следующего кратного 4;если у вас есть значение больше 2^55-(1+2+4), они будут округлены до следующего кратного 8 и т. д.

...