затем более высокое/ниже число двойной точности IEEE

Сводка ArrayList с ArrayDeque предпочтительны в [1 147] многие [еще 1147] примеры использования, чем LinkedList. Если Вы не sure  — только запустите с ArrayList.

LinkedList и ArrayList две различных реализации интерфейса List. LinkedList реализации это с двунаправленным связанным списком. ArrayList реализации это с динамично изменяющим размеры массивом.

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

Для [1 145] LinkedList

  • get(int index) , O (n) (с [1 149] шаги n/4 в среднем)
  • add(E element) , O (1)
  • add(int index, E element) O (n) (с [1 152] шаги n/4 в среднем), но O (1) когда index = 0 <---, который основное преимущество [1 113]
  • remove(int index) O (n) (с [1 155] шаги n/4 в среднем)
  • Iterator.remove(), O (1) . <---, который основное преимущество [1 116]
  • ListIterator.add(E element) O (1) , Это - одно из основных преимуществ [1 118]

Примечание: для Многих операций нужно шаги n/4 в среднем, постоянный количество шагов в лучшем случае (например, индекс = 0), и , шаги n/2 в худшем случае (середина списка) глоток>

Для [1 146] ArrayList

  • get(int index) O (1) <---основное преимущество [1 121]
  • add(E element) O (1) амортизировано, но O (n) худший случай, так как массив должен быть изменен и скопировал
  • add(int index, E element), , O (n) (с [1 165] шаги n/2 в среднем)
  • remove(int index) , O (n) (с [1 167] шаги n/2 в среднем)
  • Iterator.remove() , O (n) (с [1 169] шаги n/2 в среднем)
  • ListIterator.add(E element) O (n) (с [1 171] шаги n/2 в среднем)

Примечание: для Многих операций нужно шаги n/2 в среднем, постоянный количество шагов в лучшем случае (конец списка), шаги n в худшем случае (запустите списка) , глоток>

LinkedList допускает постоянно-разовые вставки или удаления итераторы использования , но только последовательный доступ элементов. Другими словами, можно обойти список вперед или назад, но нахождение положения в списке занимает время пропорциональное размеру списка. Javadoc заявляет "операции, что индекс в список пересечет список с начала или конца, какой бы ни ближе" , таким образом, те методы O (n) ( шаги n/4) в среднем, хотя O (1) для [1 128].

ArrayList, с другой стороны, позволяют быстро случайный доступ для чтения, таким образом, можно захватить любой элемент в постоянное время. Но добавление или удаление отовсюду, но конец требуют, чтобы смещение всех последних элементов, или сделало открытие или заполнило разрыв. Кроме того, если Вы добавляете больше элементов, чем способность основного массива, новый массив (1.5 раза размер) выделяется, и старый массив копируется в новый, таким образом добавление к ArrayList O (n) в худшем случае, но постоянно в среднем.

Так в зависимости от операций Вы намереваетесь сделать, необходимо выбрать реализации соответственно. Итерация по любому виду Списка является практически одинаково дешевой. (Выполняющий итерации по ArrayList технически быстрее, но если Вы не делаете что-то действительно чувствительное к производительности, Вы не должны волноваться об этом - они - оба константы.)

основные преимущества использования LinkedList возникают, когда Вы снова используете существующие итераторы, чтобы вставить и удалить элементы. Эти операции могут тогда быть сделаны в [1 181] O (1) путем изменения списка локально только. В списке массива остаток от массива должен быть , переместился (т.е. скопировал). С другой стороны, ища в LinkedList средства, переходящие по ссылкам в [1 183] O (n) ( шаги n/2) для худшего случая, тогда как в ArrayList желаемое положение может быть вычислено математически и получено доступ в [1 185] O (1) .

Другое преимущество использования LinkedList возникает, когда Вы добавляете или удаляете из заголовка списка, так как те операции O (1) , в то время как они O (n) для [1 136]. Обратите внимание, что ArrayDeque может быть хорошая альтернатива [1 138] для добавления и удаления от главы, но это не List.

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

начальная способность по умолчанию ArrayList довольно мала (10 от Java 1.4 - 1.8). Но так как конкретная реализация является массивом, массив должен быть изменен, если Вы добавляете много элементов. Для предотвращения высокой стоимости изменения размеров, когда Вы знаете, что собираетесь добавить много элементов создайте ArrayList с более высокой начальной мощностью.

21
задан mskfisher 10 May 2012 в 17:13
поделиться

4 ответа

Для этого есть функции, но они могут зависеть от того, какой язык вы используете. Два примера:

  • если у вас есть доступ к приличной математической библиотеке C99, вы можете использовать nextafter (и его варианты с плавающей запятой и long double, nextafterf и nextafterl ]); или семейство nexttoward (которое принимает длинный двойной аргумент).

  • если вы пишете Fortran, у вас будет ближайший внутренний доступный

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

13
ответ дан 29 November 2019 в 21:24
поделиться

Я не уверен, что понимаю вашу проблему. Несомненно, стандарт IEEE полностью единообразен ? Например, посмотрите этот отрывок из статьи википедии для чисел с двойной точностью.

3ff0 0000 0000 0000   = 1
3ff0 0000 0000 0001   = 1.0000000000000002, the next higher number > 1
3ff0 0000 0000 0002   = 1.0000000000000004

Что не так с простым увеличением младшего бита, в двоичном или шестнадцатеричном представлении?

Что касается специальных чисел (бесконечность, NaN и т. д.), они хорошо определены, и их не так много. Пределы определены аналогичным образом.

Поскольку вы, очевидно, изучили это, я полагаю, что у меня не тот конец палки. Если этого недостаточно для решения вашей проблемы, не могли бы вы прояснить, чего вы хотите достичь? Какая у вас здесь цель?

хотите достичь? Какая у вас здесь цель?

хотите достичь? Какая у вас здесь цель?

1
ответ дан 29 November 2019 в 21:24
поделиться

Да, способ есть. В C #:

       public static double getInc (double d)
        {
                // Check for special values
                if (double.IsPositiveInfinity(d) || double.IsNegativeInfinity(d))
                    return d;
                if (double.IsNaN(d))
                    return d;

                // Translate the double into binary representation
                ulong bits = (ulong)BitConverter.DoubleToInt64Bits(d);
                // Mask out the mantissa bits
                bits &= 0xfff0000000000000L;
                // Reduce exponent by 52 bits, so subtract 52 from the mantissa.
                // First check if number is great enough.
                ulong testWithoutSign = bits & 0x7ff0000000000000L;
                if (testWithoutSign > 0x0350000000000000L)
                  bits -= 0x0350000000000000L;
                else
                  bits = 0x0000000000000001L;
                return BitConverter.Int64BitsToDouble((long)bits);
}

Увеличение можно складывать и вычитать.

2
ответ дан 29 November 2019 в 21:24
поделиться

Как говорит Торстен С., это можно сделать с помощью класса BitConverter, но его метод предполагает, что метод DoubleToInt64Bits возвращает внутреннюю байтовую структуру double, а это не так. Целое число, возвращаемое этим методом, на самом деле возвращает количество представимых двоек от 0 до ты. Т.е. наименьшая положительная двойка представлена 1, следующая по величине двойка - 2 и т.д. и т.п. Отрицательные числа начинаются с long.MinValue и уходят от 0d.

Поэтому вы можете сделать что-то вроде этого:

public static double NextDouble(double value) {

    // Get the long representation of value:
    var longRep = BitConverter.DoubleToInt64Bits(value);

    long nextLong;
    if (longRep >= 0) // number is positive, so increment to go "up"
        nextLong = longRep + 1L;
    else if (longRep == long.MinValue) // number is -0
        nextLong = 1L;
    else  // number is negative, so decrement to go "up"
        nextLong = longRep - 1L;

    return BitConverter.Int64BitsToDouble(nextLong);
}

Это не касается Infinity и NaN, но вы можете проверить их и работать с ними как угодно, если вас это беспокоит.

5
ответ дан 29 November 2019 в 21:24
поделиться
Другие вопросы по тегам:

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