почему результат boost :: math :: float_distance (1.0, 0.0) такой большой? [Дубликат]

Буквально самый простой способ исправить NullReferenceExeption имеет два пути. Если у вас есть GameObject, например, с прикрепленным скриптом и переменной с именем rb (rigidbody), эта переменная начнет пустую, когда вы начнете игру. Вот почему вы получаете NullReferenceExeption, потому что на компьютере нет данных, хранящихся в этой переменной.

В качестве примера я буду использовать переменную RigidBody. Мы можем добавить данные действительно легко на самом деле несколькими способами:

  1. Добавить RigidBody к вашему объекту с помощью AddComponent> Физика> Rigidbody Затем зайдите в свой скрипт и введите rb = GetComponent<Rigidbody>();. Эта строка кода работает лучше всего под ваши функции Start() или Awake().
  2. Вы можете добавить компонент программно и назначить переменную одновременно с одной строкой кода: rb = AddComponent<RigidBody>();

Дальнейшие заметки: если вы хотите, чтобы единство добавлялось компонент для вашего объекта, и вы, возможно, забыли добавить его, вы можете ввести [RequireComponent(typeof(RigidBody))] над объявлением класса (пробел ниже всех ваших приложений). Наслаждайтесь и получайте удовольствие от игр!

87
задан polygenelubricants 5 June 2010 в 03:51
поделиться

6 ответов

Java double s находятся в формате IEEE-754 , поэтому они имеют 52-битную дробь; между любыми двумя соседними степенями двух (включая один и исключая следующий), поэтому будет 2 до 52-й степени, другой double s (т. е. 4503599627370496 из них). Например, это число различных double s между 0,5 включенными и 1.0 исключенными, и точно, что многие также лежат между 1.0 включенными и 2.0 исключенными и т. Д.

Подсчет doubles между 0.0 и 1.0 сложнее, чем между двумя степенями, потому что в этом диапазоне есть много полномочий из двух, а также попадает в тернистые проблемы денормализованных чисел. 10 из 11 бит экспонентов охватывают диапазон, о котором идет речь, поэтому, включая денормализованные числа (и, я думаю, несколько видов NaN), вы имели бы 1024 раз double s как лежащие между степенями двух - в любом случае не более 2**62. Исключение denormalized & amp; c, я считаю, что счет будет 1023 раза 2**52.

Для произвольного диапазона, например «100-1100,1», это еще сложнее, потому что верхняя граница не может быть точно представлена ​​как double (не являясь точным кратным любой мощности двух). В качестве удобного приближения, поскольку прогрессия между степенями двух линейна, вы можете сказать, что указанный диапазон равен 0.1 / 64 th промежутка между окружающими силами двух (64 и 128), поэтому вы ожидаете, что

(0.1 / 64) * 2**52

отличается double s - который приходит к 7036874417766.4004 ... дает или принимает один или два; -).

62
ответ дан Alex Martelli 24 August 2018 в 22:47
поделиться
  • 1
    @Alex: просто отметить, когда я написал от 100 до 100,1, я неправильно написал. Я имел в виду от 100 до 101. В принципе, между N и N + 1 для произвольного N. – polygenelubricants 5 June 2010 в 04:15
  • 2
    @Alex: так позвольте мне получить это прямо: может быть не более 2**64 возможных двойных значений (так как это 64-разрядный тип), и, по-видимому, ОГРОМНАЯ пропорция этих значений лежит между 0..1? – polygenelubricants 5 June 2010 в 04:19
  • 3
    @polygene, да и да - в частности, примерно одна четверть возможных значений (для любого «нормального» представления с плавающей запятой любого базового и экспоненциального числа с длиной фракции) находится между 0.0 и 1.0 (другая четверть от 1.0 до бесконечности и оставшаяся половина на отрицательной половине вещественной оси). По существу, половина значений экспоненты (с нормальным смещением, на полпути в пределах ее диапазона) представляют отрицательные мощности основания, поэтому числа & lt; 1,0. – Alex Martelli 5 June 2010 в 04:31
  • 4
    @polygenelubricants: для многих приложений диапазон от 0 до 1 намного, гораздо более важный и интересный, чем диапазон от 100 до 101, поэтому он получает большую долю значений. Например, в физике вам часто приходится иметь дело с смехотворно малыми значениями, такими как гравитационная постоянная Ньютона на 6.67e-11. Имея хорошую точность, более полезно, чем между 100 и 101. Для получения дополнительной информации прочитайте floating-point-gui.de . – Michael Borgwardt 5 June 2010 в 08:36
  • 5
    Вы также можете масштабировать любое число от 0,0 до 1,0, отслеживая масштаб отдельно, что дает меньше ошибок при вычислении. Приятно, когда вся цифровую строку можно сопоставить между двумя номерами! – codekaizen 8 July 2010 в 20:27

Другие уже объяснили, что в диапазоне [0.0, 1.0] около 2 ^ 62 удваивается. (Неудивительно: почти 2 ^ 64 отдельных конечных двойника, из них половина положительна, а примерно половина тех равна & lt; 1.0.)

Но вы говорите генераторы случайных чисел: обратите внимание, что генератор случайных чисел, генерирующий числа от 0,0 до 1,0 , вообще не может производить все эти числа; обычно он будет генерировать числа формы n / 2 ^ 53 с n целым числом (см., например, документацию по Java для nextDouble ). Таким образом, обычно есть только около 2 ^ 53 (+/- 1, в зависимости от того, какие конечные точки включены) возможные значения для выхода random(). Это означает, что большинство удвоений в [0.0, 1.0] никогда не будут сгенерированы.

6
ответ дан Mark Dickinson 24 August 2018 в 22:47
поделиться

В статье новая математическая математика Java, часть 2: числа с плавающей запятой из IBM предлагает следующий фрагмент кода для решения этой проблемы (в поплавках, но я подозреваю, что это работает и для удвоений):

public class FloatCounter {

    public static void main(String[] args) {
        float x = 1.0F;
        int numFloats = 0;
        while (x <= 2.0) {
            numFloats++;
            System.out.println(x);
            x = Math.nextUp(x);
        }
        System.out.println(numFloats);
    }
}

У них есть этот комментарий об этом:

Оказывается, ровно 8,388,609 поплавок от 1,0 до 2,0 включительно; большая, но едва ли бесчисленная бесконечность вещественных чисел, существующих в этом диапазоне. Последовательные числа составляют около 0,0000001 друг от друга. Это расстояние называется ULP для единицы наименьшей точности или единицы в последнем месте.

3
ответ дан Mark Rushakoff 24 August 2018 в 22:47
поделиться
  • 1
    Да, но это для float, not double - float s имеет дробную долю в 23 бита, поэтому 2**23 -> 8388608 разные значения между смежными степенями двух ("включительно" , конечно, означает, что вы должны посчитать еще одну, следующую силу двух). double s имеют 52-битные дроби! – Alex Martelli 5 June 2010 в 04:01
  • 2
    @Alex: Думаю, мне придется оставить программу (измененную для парных) до конца юниверса или так до того, как я получу результаты ... :( – Mark Rushakoff 5 June 2010 в 04:04
  • 3
    Я чувствую себя глупым; Я просто написал эквивалент double и подумал «Эй, я отвечу на свой вопрос примерно через 5 минут ...». – polygenelubricants 5 June 2010 в 04:05
  • 4
    @polygene: Это похоже на проблему Project Euler, где очевидный подход недостижим для вычисления, но для произвольного случая должна быть какая-то блестяще простая формула ... – Mark Rushakoff 5 June 2010 в 04:10
  • 5
    возможно, не с действительно наддуваемым суперкомпьютером: на машине, занимающей всего лишь наносекунду для запуска внутреннего цикла, подсчет с double между соседними степенями двух займет около 52 дней (конечно, println будет very < / i> вряд ли будет работать так быстро, несмотря ни на что, так что давайте предположим, что одно утверждение уходит ;-). Я думаю, что на мощной, но реалистичной машине можно потратить год или меньше ;-). – Alex Martelli 5 June 2010 в 04:18

Java double - это номер двоичного кода IEEE 754.

Это означает, что нам нужно рассмотреть:

  1. Mantissa - 52 бит
  2. Показатель - 11-битное число с 1023 смещением (т. е. с добавлением 1023)
  3. Если показатель степени равен 0, а мантисса не равна нулю, то число называется ненормированным

Это в основном означает, что существует всего 2 ^ 62-2 ^ 52 + 1 возможных двойных представлений, которые в соответствии со стандартом находятся между 0 и 1. Заметим, что 2 ^ 52 + 1 - это удаление случаев ненормированных чисел.

Помните, что если мантисса положительна, а показатель отрицательного числа положителен, но меньше 1: -)

Для других чисел это немного сложнее, Целочисленные числа краев могут не отображаться точным образом в представлении IEEE 754 и потому, что есть другие биты, используемые в экспоненте, чтобы они могли представлять числа, поэтому чем больше число, тем ниже различные значения.

1
ответ дан njsf 24 August 2018 в 22:47
поделиться

Каждое значение double, представление которого находится между 0x0000000000000000 и 0x3ff0000000000000, находится в интервале [0.0, 1.0].

Интервал [1.0, 2.0] соответствует представлениям между 0x3ff0000000000000 и 0x400000000000000; это 2 ^ 52 различных значения.

Интервал [100,0, 101,0] соответствует представлениям между 0x4059000000000000 и 0x4059400000000000; это 2 ^ 46 различных значений.

Не существует удвоений между 10 ^ 100 и 10 ^ 100 + 1. Ни одно из этих чисел не представляется в двойной точности, и между ними нет двойников. Ближайшие два числа двойной точности:

99999999999999982163600188718701095...

и

10000000000000000159028911097599180...
35
ответ дан Stephen Canon 24 August 2018 в 22:47
поделиться
  • 1
    +1, для хорошо поддерживаемого точного ответа. (Если вы придирчивы к подсчету конечных точек, помните, что +0.0 и -0.0 имеют разные представления.) – Jim Lewis 5 June 2010 в 05:11
  • 2
    +1, такой конец поворота! Почувствовал, как я читал сценарий М. Ночной Шьямалан! – polygenelubricants 12 June 2010 в 08:37
  1. 2 ^ 53 - размер значащей / мантиссы 64-битного числа с плавающей запятой, включая скрытый бит.
  2. Примерно да, поскольку sifnificand фиксирован, но экспонента изменяется.

Дополнительную информацию см. в статье wikipedia .

2
ответ дан Yann Ramin 24 August 2018 в 22:47
поделиться
  • 1
    Ваш ответ на 2 противоречит тому, как я понимаю работу FP. – polygenelubricants 5 June 2010 в 04:01
  • 2
    Я думаю, что 1 ошибочно, потому что скрытый бит всегда один - поэтому значения 2^52, not 2^53 distinct (между соседними степенями двух, один включен, а следующий исключен - не между 0.0 и 1.0!). – Alex Martelli 5 June 2010 в 04:03
Другие вопросы по тегам:

Похожие вопросы: