Простая задача расчета с Flex - PullRequest
1 голос
/ 20 января 2010

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

Начиная с 69,8:

Calculating MM to pixel from: 69.8 mm
69.8*300 = 20940
20940 / 2.54 = 8244.094488188975
8244.094488188975 / 10 = 824.4094488188975

И подсчет обратно:

Calculating pixel to MM from: 824.4094488188975
824.4094488188975/300 = 2.7480314960629917
2.7480314960629917 * 2.54 = 6.979999999999999
6.979999999999999 * 10 = 69.79999999999998

Мы хотели 69,8, но в итоге получили 69,79999999999998. Я отслеживал процесс, используя простой Windows Calc, и первое, что он ошибся, это 20940 / 2,54 = 8244,094488188975, который должен быть 8244,094488188976.

Любая помощь в этом была бы великолепна.

Ответы [ 2 ]

7 голосов
/ 20 января 2010

Хорошо, это не столько вопрос Flex, сколько вопрос общего программирования. Задумывались ли вы, как именно цифры хранятся в компьютере? Подробности в математике, но я постараюсь выразиться проще. Вы знаете, что существует бесконечное количество различных действительных чисел (например, одинаковых точек на непрерывной линии), но на вашем компьютере вы храните все как нули и единицы, а их ограниченное количество (32 или 64 «бита»). Так что теперь у нас есть проблема - как представить неограниченное количество чисел в ограниченном пространстве. Идея, используемая в числе с плавающей запятой (те, которые могут иметь значения с «точкой», такой как 1.03 или 4.2232), заключается в том, что, поскольку вы не можете иметь их все, вы округляете число до ближайшего к вам.

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

Так что с числами с плавающей запятой стоит похожая идея, с дополнительным поворотом - числа гораздо плотнее около 0, чем далеко от него, где «пустое пространство» между ними становится действительно большим. Например, если вы вычтете 10000 из максимального значения, которое может получить число, оно все равно останется тем же, потому что нет такого номера, который был бы настолько близок к нему, чтобы иметь значение при поиске ближайшего.

    trace (Number.MAX_VALUE == Number.MAX_VALUE-10000);
    //  returns "true"
    trace (200000 == 200000 - 10000);
    //  returns "false"

Итак, ваша проблема заключается в предположении, что числа абсолютно точны, а они нет, вы всегда округляете. Число в as3 соответствует стандарту IEEE-754 двойной точности, и именно так оно решает, какое число оно имеет, а какое округляет.

Посмотрите на это:

trace (8244.094488188976);
// returns "8244.094488188975"

Дальнейшее чтение:

Плавающая точка

IEEE_754-2008

0 голосов
/ 23 января 2010

Ответ Adobe в TechNote под названием Flash возвращает ошибочные результаты для определенных математических вычислений кратко выражает это:

Это факт жизни в приложениях, которые используют арифметику с плавающей запятой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...