Компьютер сначала округляет числа в операциях или округляет результат? - PullRequest
0 голосов
/ 09 апреля 2020

Например, в операциях 9.4 - 9.0 - 0.4: компьютер сначала округляет каждое число и сохраняет или выполняет вычисления с помощью некоторых дополнительных битов (этот пример в формате двойной точности), а затем округляет результат ? Это сохраненные значения, но вы не знали, как выполнить эту операцию вручную, чтобы проверить, округляет ли она каждое число вначале или нет.

двоичное (9.4) = 0 10000000010 0010110011001100110011001100110011001100110011001100110011001100110011001101

двоичное (-9,0) = 1 10000000010 0010000000000000000000000000000000000000000000000000

двоичный (-0,4) = 1 01111111101 10011001100110011001100110011001100110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Обычно компьютер преобразует цифры в 9.4 - 9.0 - 0.4 в числа во внутренней форме, а затем выполняет арифметические операции c. Эти преобразования обычно округляют свои результаты.

Рассмотрим текст в исходном коде 9.4 - 9.0 - 0.4. Там нет ничего. Этот текст представляет собой строку, состоящую из символов. Он содержит символы «9», «.», «4», «», «-» и т. Д. Обычно компьютер преобразует этот текст в другие формы для обработки. Вы могли бы написать программное обеспечение, которое работает с числами в текстовом формате, но это редко. Обычно, когда мы используем язык программирования, скомпилированный или интерпретированный, цифры в этом тексте будут преобразованы во некоторую внутреннюю форму. («Цифра» - это последовательность символов, представляющих число. Таким образом, «9,4» - это цифра, представляющая 9,4.)

двоичный код IEEE-754 - очень распространенная плавающая точка. В этом формате каждое представимое число выражается в единицах некоторой степени двойки. Например, числа .125, .250, .375 и .500 также представимы, потому что они кратны 1/8, что составляет 2 -3 . Однако 9.4 не кратно какой-либо степени двойки, поэтому он не может быть представлен в двоичном64 IEEE-754.

Когда 9.4 преобразуется в двоичную 64, ближайшее представимое значение составляет 9.4000000000000003552713678800500929355621337890625. (Это кратное 2 -50 , которое является степенью двойки, используемой при представлении чисел около 9,4, в частности чисел от 8 [включительно] до 16 [исключительно.)

9 представимо в двоичном 64, поэтому 9 преобразуется в 9.

0,4 не представляется в двоичном 64. Когда 0.4 преобразуется в двоичный код64, ближайшее представимое значение составляет 0,40000000000000002220446049250313080847263336181640625. Это кратное 2 −54 , которое является степенью двойки, используемой для чисел от ¼ до ½.

В 9.4 - 9.0 - 0.4, результат первого вычитания составляет 0,4000000000000003552713678800500929355621337890625. Это точно представимо, поэтому в этой точке нет округления. Затем, когда вычитается 0.4, после того, как оно было преобразовано в указанное выше значение, результат равен 0,00000000000000033306690738754696212708950042724609375. Это также точно представимо, поэтому здесь снова нет округления.

Выше описано, что происходит, если повсеместно используется binary64. Многие языки программирования или их конкретные реализации c используют двоичный код64. Некоторые могут использовать другие форматы. Некоторые языки позволяют реализациям использовать сочетание форматов - они могут использовать более широкий формат, чем binary64, для выполнения вычислений и преобразовывать в binary64 для конечного результата. Это может привести к тому, что вы увидите результаты, отличные от приведенных выше.

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

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

1 голос
/ 09 апреля 2020

Некоторые программы или некоторые машины могут использовать дополнительную точность для промежуточных результатов. Это зависит от множества факторов: доступное оборудование, какой язык программирования вы используете, какой компилятор вы используете, какие опции вы передали компилятору и т. Д. c. Например, программы, скомпилированные для процессора Intel, могут иногда использовать 80-битную точность для промежуточных результатов, если они скомпилированы с использованием x87 инструкций .

. В остальном ответе я приму все операции выполняются в 64-битных числах с плавающей запятой двойной точности.

Каждое число округляется в первую очередь, а результаты округляются тоже. Например, 9.4 нельзя представить точно в виде двоичного числа с плавающей запятой, поэтому 9.4 в программе округляется до до ближайшего числа с плавающей запятой . При 64-битной точности с плавающей точкой точное математическое значение этого числа:

9.4000000000000003552713678800500929355621337890625

Таким образом, 9,4 «округляется» до 9,4000000000000003552713678800500929355621337890625.

Аналогично, 0,4 нельзя представить точно. Он «округляется» до:

0.40000000000000002220446049250313080847263336181640625

Возможно, необходимо также округлить результаты вычислений. Умножение двух чисел N-di git дает число с 2N цифрами. Если вы можете хранить только N цифр, что будет с остальными? Они округлены.

Здесь вы спрашиваете о вычитании. С числами разных величин результат вычитания должен быть округлен. В частном случае (9.4 - 9) - 0.4 все числа имеют одинаковую величину, поэтому округление результатов не происходит, а операции математически точны:

При условии, что все числа хранятся как 64-разрядные числа с плавающей запятой, вычисляется первое вычитание :

9.4000000000000003552713678800500929355621337890625 - 9.0 =
0.4000000000000003552713678800500929355621337890625

Второе вычитание вычисляет:

  0.4000000000000003552713678800500929355621337890625 
- 0.40000000000000002220446049250313080847263336181640625
----------------------------------------------------------
  0.00000000000000033306690738754696212708950042724609375
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...