Каждое плавание может быть выражено точно как двойное?

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

16
задан MPelletier 30 April 2012 в 04:09
поделиться

10 ответов

Да.

Доказательство перечислением всех возможных случаев:

public class TestDoubleFloat  {
    public static void main(String[] args) {
        for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
            float f1 = Float.intBitsToFloat((int) i);
            double d = (double) f1;
            float f2 = (float) d;
            if (f1 != f2) {
                if (Float.isNaN(f1) && Float.isNaN(f2)) {
                    continue; // ok, NaN
                }
                fail("oops: " + f1 + " != " + f2);
            }
        }
    }
}

концы за 12 секунд на моей машине. 32 бита маленькие .

24
ответ дан 30 November 2019 в 16:19
поделиться

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

5
ответ дан 30 November 2019 в 16:19
поделиться

Да, плавания являются подмножеством, удваивается. Оба плавания и удваиваются, имеют форму (знак * * 2^b). Различие между плаваниями и удваивается, число битов в & b. С тех пор удваивается, имеют больше битов в наличии, присваивая значение плавающее двойному эффективно средства, вставляющие дополнительные 0 битов.

5
ответ дан 30 November 2019 в 16:19
поделиться

Поскольку все уже сказали, "нет". Но это - на самом деле "да" к самому вопросу, т.е. каждое плавание может быть точно выраженным как двойное. Путание.:)

3
ответ дан 30 November 2019 в 16:19
поделиться

Если я читаю спецификация языка правильно (и как все остальные подтверждают), нет такого значения.

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

(разъяснение: не было бы никакого изменения, пока значение было достаточно маленьким, чтобы быть сохраненным в плавании; очевидно, если бы значение было слишком многими битами, которые будут сохранены в плавании для начала, то бросание от дважды для плавания привело бы к потере точности.)

3
ответ дан 30 November 2019 в 16:19
поделиться

@KenG: Этот код:

float a = 0.1F
println "a=${a}"
double d = a
println "d=${d}"

сбои, не потому что 0.1f не может быть точно представлен. Вопрос был, "там значение плавающее, которое не может быть представлено как двойное", которое не доказывает этот код. Хотя 0.1f не может быть сохранен точно, значение, что данного (который не является 0.1f точно) может быть сохранен как двойное (который также не будет 0.1f точно). Принимая Intel FPU, комбинацию двоичных разрядов для:

0 01111011 10011001100110011001101

и комбинация двоичных разрядов для d:

0 01111111011 100110011001100110011010 (сопровождаемый партиями больше нулей)

, который имеет тот же знак, экспонента (-4 в обоих случаях) и та же дробная часть (разделенный пробелами выше). Различие в выводе происходит из-за положения второй ненулевой цифры в числе (первым является 1 после точки), который может только быть представлен с двойным. Код, который производит формат строки, хранит промежуточные значения в памяти и характерен для плаваний и удваивается (т.е. существует функция дважды до строки и другое плавание к строке). Если бы к строковой функции был оптимизирован для использования стека FPU для хранения промежуточных результатов процесса к строке, вывод был бы тем же для плавания и дважды так как FPU использует то же, больший формат (80bits) и для плавания и для дважды.

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

1
ответ дан 30 November 2019 в 16:19
поделиться

Глюк: NaN с выдержит сравнение по-другому после (или действительно прежде) преобразование.

Это, однако, не делает недействительным ответы, уже данные.

0
ответ дан 30 November 2019 в 16:19
поделиться

Я взял код, который Вы перечислили и решили попробовать его в C++, так как я думал, что это могло бы выполниться немного быстрее, и значительно легче сделать небезопасный кастинг.:-D

я узнал, что для верных номеров, преобразование работает и Вы получаете точное поразрядное представление после броска. Однако для нечисел, например, 1.#QNAN0, и т.д., результат будет использовать упрощенное представление нечисла, а не точные биты источника. Например:

**** отказ **** 2140188725 | 1.#QNAN0 - 0xa0000000 0x7ffa1606

я бросил неподписанный интервал для плавания затем, чтобы удвоиться и отступить для плавания. Результатами номер 2140188725 (0x7F90B035) в NAN и преобразовывающий в двойной и назад является все еще NAN, но не точный тот же NAN.

Вот простой код C++:

typedef unsigned int uint;
for (uint i = 0; i < 0xFFFFFFFF; ++i)
{
    float f1 = *(float *)&i;
    double d = f1;
    float f2 = (float)d;
    if(f1 != f2)
        printf("**** FAILURE **** %u | %f -- 0x%08x 0x%08x\n", i, f1, f1, f2);
    if ((i % 1000000) == 0)
        printf("Iteration: %d\n", i);
}
0
ответ дан 30 November 2019 в 16:19
поделиться

Ответ на первый вопрос да, ответ на, 'другими словами', однако нет. При изменении теста в коде, чтобы быть if (!(f1 != f2)), ответ на второй вопрос становится да - это распечатает 'Успех' для всех значений плавающих.

0
ответ дан 30 November 2019 в 16:19
поделиться

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

то, Когда Вы идете от теории до действительности, - когда у Вас будут проблемы. Я не знаю, интересовались ли Вы теорией или реализацией. Если это - реализация тогда, можно быстро попасть в беду.

IEEE является ужасным форматом, мое понимание, что он был намеренно разработан, чтобы быть столь жестким, что никто не мог встретить его и позволить рынку ловить до Intel (это некоторое время вернулось), обеспечение большего количества конкуренции. Если это верно, что перестало работать, так или иначе мы застреваем с этой ужасной спецификацией. Что-то как формат TI намного выше к реальному миру таким количеством способов. У меня нет соединения или с компанией или с любым из этих форматов.

Благодаря этой спецификации существуют очень немногие, если любые fpus, которые на самом деле встречают ее (в аппаратных средствах или даже в аппаратных средствах плюс операционная система), и те, которые действительно часто перестали работать на следующем поколении. (Google: TestFloat). Проблемы в эти дни имеют тенденцию заключаться в интервале, чтобы плавать и плавать к интервалу и не единственные, чтобы удвоиться и удвоиться до сингла, поскольку Вы определили выше. Конечно, что операция fpu собирается выполнить, чтобы сделать то преобразование? Добавить 0? Умножиться на 1? Зависит от fpu и компилятора.

проблема с IEEE, связанным с Вашим вопросом выше, состоит в том, что существует больше чем один путь число, не, каждое число, но много чисел может быть представлено. Если бы я хотел повредить Ваш код, то я запустил бы с минус нуль в надежде, что одна из этих двух операций преобразует его в плюс нуль. Тогда я попробовал бы denormals. И это должно перестать работать с передачей сигналов nan, но Вы вызвали это как известное исключение.

проблема состоит в том, что знак "равно", вот правило номер один о плавающей точке, никогда не используйте знак "равно". Равняется немного сравнения не сравнение значения, если у Вас будет два значения, представленные по-разному (плюс нуль и минус нуль, например), то разрядное сравнение перестанет работать даже при том, что это - то же число. Больше, чем и меньше, чем сделаны в fpu, равняется, сделан с целым числом alu.

я понимаю, что Вы, вероятно, использовали равное для объяснения проблемы и не обязательно кода, за которым Вы хотели следовать или привести к сбою.

0
ответ дан 30 November 2019 в 16:19
поделиться
Другие вопросы по тегам:

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