Действительно ставит в тупик (), возвращают что-то, что это является точно представимым?

Контекст этой функции onload должен быть исходным XMLHttpRequest, но при использовании функции стрелки у вас нет назначенного контекста, поэтому он, скорее всего, будет родительской областью или окном. Это будет проблемой.

10
задан Jim Hunziker 20 January 2009 в 21:40
поделиться

3 ответа

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

14
ответ дан 3 December 2019 в 20:07
поделиться

Если результат пола () не является точно представимым, чем Вы ожидаете, что значение d будет? Конечно, если у Вас есть представление числа с плавающей точкой в переменной, затем по определению это является точно представимым не так ли? У Вас есть представление в d...

(Кроме того, ответ Mehrdad корректен для 32 битов ints. В компиляторе с 64 битами дважды и интервале на 64 бита, у Вас есть больше проблем, конечно...),

Править: Возможно, Вы подразумевали, что "теоретический результат пола (), т.е. самое большое целочисленное значение, меньше чем или равное аргументу, не может быть представимым как интервал". Это, конечно, верно. Простой способ показать это для системы, где интервал составляет 32 бита:

int max = 0x7fffffff;
double number = max;
number += 10.0;
double f = floor(number);
int oops = (int) f;

Я не могу помнить бесцеремонно, что делает C, когда преобразования от плавающей точки до целочисленного переполнения..., но он собирается произойти здесь.

Править: Существуют другие интересные ситуации для рассмотрения также. Вот некоторый код C# и результаты - я предположил бы, по крайней мере, что подобные вещи произойдут в C. В C#, double определяется, чтобы быть 64 бита и так long.

using System;
class Test
{
    static void Main()
    {
        FloorSameInteger(long.MaxValue/2);
        FloorSameInteger(long.MaxValue-2);
    }

    static void FloorSameInteger(long original)
    {
        double convertedToDouble = original;
        double flooredToDouble = Math.Floor(convertedToDouble);
        long flooredToLong = (long) flooredToDouble;

        Console.WriteLine("Original value: {0}", original);
        Console.WriteLine("Converted to double: {0}", convertedToDouble);
        Console.WriteLine("Floored (as double): {0}", flooredToDouble);
        Console.WriteLine("Converted back to long: {0}", flooredToLong);
        Console.WriteLine();
    }
}

Результаты:

Исходное значение: 4611686018427387903
Преобразованный в дважды: 4.61168601842739E+18
Настеленный пол (как дважды): 4.61168601842739E+18
Преобразованный назад в долго: 4611686018427387904

Исходное значение: 9223372036854775805
Преобразованный в дважды: 9.22337203685478E+18
Настеленный пол (как дважды): 9.22337203685478E+18
Преобразованный назад в долго:-9223372036854775808

Другими словами:

(long) floor((double) original)

не всегда то же как original. Это не должно стать никаким удивлением - существуют более длинные значения, чем удваивается (учитывая значения NaN), и много из удваивается, не целые числа, таким образом, мы не можем ожидать, что каждый долго будет точно представимым. Однако все целые числа на 32 бита являются представимыми, как удваивается.

3
ответ дан 3 December 2019 в 20:07
поделиться

Думаю, вы немного не понимаете, о чем хотите спросить. floor (3 + 0.5) не очень хороший пример, потому что 3, 0.5 и их сумма точно представлены в любом реальном формате с плавающей запятой. floor (0,1 + 0,9) будет лучшим примером, и реальный вопрос здесь не в том, является ли результат floor точно представимым, а в том, нет ли неточности чисел до to вызов floor приведет к возврату значения, отличного от ожидаемого, если бы все числа были точными. В этом случае я считаю, что ответ положительный, но это во многом зависит от ваших конкретных чисел.

Я предлагаю другим раскритиковать этот подход, если он плохой, но одним из возможных решений может быть умножение вашего числа на (1.0 + 0x1p-52) или что-то подобное, прежде чем звонить на этаж ] (возможно, было бы лучше использовать nextafter ). Это могло бы компенсировать случаи, когда ошибка в последнем двоичном разряде числа приводит к тому, что оно падает чуть ниже, а не точно на целочисленное значение, но это не будет учитывать ошибки, которые накопились за несколько операций. Если вам нужен такой уровень числовой стабильности / точности, вам нужно либо провести глубокий анализ, либо использовать библиотеку произвольной точности или точной математики, которая может правильно обрабатывать ваши числа.

2
ответ дан 3 December 2019 в 20:07
поделиться
Другие вопросы по тегам:

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