Golang Как конвертировать большой uint64 в float? [Дубликат]

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

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

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
147
задан 7 revs, 5 users 68% 12 June 2014 в 21:25
поделиться

4 ответа

173
ответ дан 7 revs, 5 users 89% 19 August 2018 в 11:15
поделиться

Хотя все остальные ответы хороши, все еще одна вещь отсутствует:

Невозможно представить иррациональные числа (например, π, sqrt(2), log(3) и т. д.) точно!

И на самом деле их называют иррациональными. Никакого количества бит-памяти в мире было бы достаточно, чтобы провести хотя бы один из них. Только символическая арифметика способна сохранить свою точность.

Хотя, если вы ограничиваете свои математические потребности рациональными числами, только проблема точности становится управляемой. Вам нужно будет сохранить пару (возможно очень больших) целых чисел a и b, чтобы удерживать число, представленное фракцией a/b. Вся ваша арифметика должна быть сделана на дроби, как в математике на высшем уровне (например, a/b * c/d = ac/bd).

Но, конечно, вы все равно столкнетесь с такими же проблемами, когда pi, sqrt , log, sin и т. д.

TL; DR

Для аппаратной ускоренной арифметики может быть представлено только ограниченное количество рациональных чисел. Каждое не представимое число аппроксимируется. Некоторые числа (т. Е. Иррациональные) никогда не могут быть представлены независимо от системы.

8
ответ дан LumpN 19 August 2018 в 11:15
поделиться
  • 1
  • 2
    иррациональные числа могут быть (только) представлены в их базе. Например, pi равно 10 в базе pi – phuclv 24 June 2014 в 15:21
  • 3
    Точка остается в силе: Некоторые числа никогда не могут быть представлены независимо от системы. Вы ничего не получаете, меняя свою базу, потому что тогда некоторые другие цифры больше не могут быть представлены. – LumpN 27 June 2014 в 05:10

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

Рассмотрим фракцию 2/3

. В базе 10 хорошего ола мы обычно записываем ее как нечто вроде

  • 0.666 ...
  • 0.666
  • 0.667

Когда мы смотрим на эти представления, мы склонны связывать каждую из них с долей 2 / 3, хотя только первое представление математически равно фракции. Второе и третье представления / аппроксимации имеют ошибку порядка 0,001, что на самом деле намного хуже, чем ошибка между 9.2 и 9.1999999999999993. На самом деле, второе представление даже не округлено правильно! Тем не менее, у нас нет проблемы с 0,666 в качестве приближения числа 2/3, поэтому у нас не должно быть проблем с тем, как 9.2 аппроксимируется в большинстве программ. (Да, в некоторые программы имеют значение.)

Числовые базы

Итак, вот здесь, где числовые базы являются crutial. Если мы пытались представить 2/3 в базе 3, то

(2/3) 10 = 0,23

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

Чтобы вести эту точку домой, давайте посмотрим на 1/2. Вас может удивить, что, хотя это совершенно простое число имеет точное представление в базе 10 и 2, для него требуется повторное представление в базе 3.

(1/2) 10 = 0,510 = 0,12 = 0.1111 ... 3

Почему числа с плавающей запятой неточны?

Поскольку часто-времена они аппроксимируют рациональные, которые не могут быть представлены конечно в основании 2 ( цифры повторяются), и в целом они аппроксимируют реальные (возможно, иррациональные) числа, которые не могут быть представлены в конечном числе цифр в любой основе.

24
ответ дан Nicu Stiurca 19 August 2018 в 11:15
поделиться
  • 1
    Другими словами, base-3 идеально подходит для 1/3, так как base-10 идеально подходит для 1/10. Ни одна фракция не работает в base-2 – mhlester 20 February 2014 в 03:19
  • 2
    @mhlester Да. И вообще, base-N идеально подходит для любой фракции, знаменатель которой N или ее кратный. – Nicu Stiurca 20 February 2014 в 03:20
  • 3
    И это одна из причин, почему некоторые числовые ящики инструментов отслеживают «то, что было разделено на что», и в этом процессе может сохраняться «бесконечная точность», для всех рациональных чисел. Подобно тому, как физики любят сохранять свои уравнения символическими до последнего момента, в случае, если факторы π и т. Д. Отменены. – Floris 20 February 2014 в 03:39
  • 4
    @Floris Я также видел случаи, когда алгоритм, который выполняет только базовую арифметику (т. Е. Сохраняет рациональность ввода), определяет, был ли вход (вероятным) рациональным, выполнить математику, используя обычную арифметику с плавающей запятой, а затем переоценить рациональную приближение в конце, чтобы исправить ошибки округления. В частности, алгоритм Matlab приведенный алгоритм эшелона строки делает это, и он чрезвычайно помогает в численной стабильности. – Nicu Stiurca 20 February 2014 в 03:54
  • 5
    @SchighSchagh - интересно, я этого не знал. Я знаю, что численная стабильность - это то, что недостаточно изучено в эти дни двойной двойной точности. Это означает, что многие не знают об изяществе многих красивых алгоритмов. Мне очень нравятся алгоритмы, которые вычисляют и исправляют свои собственные ошибки. – Floris 20 February 2014 в 04:04

Почему мы не можем представить 9.2 в двоичной с плавающей запятой?

Числа с плавающей запятой (немного упрощают) систему позиционной нумерации с ограниченным числом цифр и подвижным основанием point.

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

Основными факторами 10 являются 5 и 2, поэтому в базе 10 мы можем представить любую долю вида a / (2b5c).

С другой стороны, единственным простым множителем 2 является 2, поэтому в базе 2 мы можем представлять только фракции вида a / (2b)

Почему компьютеры использовать это представление?

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

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

Однако большая проблема заключается в том, что такой формат является болью для выполнения вычислений. По двум причинам.

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

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

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

0
ответ дан plugwash 19 August 2018 в 11:15
поделиться
Другие вопросы по тегам:

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