AndreyIvanoff
@AndreyIvanoff

Вычисления с плавающей точкой?

Здравствуйте Хабровчане.

Вопрос может показаться странным но он меня приводит в тяжелое недоумение.


Я буду приводить вычисления, выполненные в MatLab:

Команда: sqrt(2) = 1.4142135623731 — 13 значащих цифр после запятой.

Команда: sqrt(98) = 9.89949493661167 — 14 значащих цифр после запятой.


Насколько я понимаю, после запятой в типе double может быть не больше 15 знаков после запятой.

И если вычислить по честному эти корни:

vpa(sqrt(2),16) = 1.414213562373095 — 15 значащих цифр.

vpa(sqrt(98),16) = 9.899494936611665 — 15 значащих цифр.


Заметим, что округление в случае 13 и 14 знаков осуществлено по всем правилам и верно.

Однако мне непонятна причина, почему функция sqrt выдает разное количество разрядов для разных цифр? Чем это вызвано и в чем логика такого поведения? Такое же я наблюдал и C-компиляторах.
  • Вопрос задан
  • 8482 просмотра
Пригласить эксперта
Ответы на вопрос 4
burdakovd
@burdakovd
«Насколько я понимаю, после запятой в типе double может быть не больше 15 знаков после запятой.» — это откуда Вы взяли?

Во первых в floating-point арифметике нет различий между «до запятой» и «после запятой» — всё переносится в «после запятой», даже та «1» или «9», что была у вас в целой части (это объясняет, случай с sqrt(2) (15-й знак был до запятой), а sqrt(98) — просто последний знак =0 ).

Во-вторых не забываем, что арифметика двоичная, а не десятичная, так что ровно 15 знаков не всегда будет, могут быть ещё чудеса. Ну и IEEE 754.
Ответ написан
Комментировать
В форматах с плавающей запятой зафиксировано не количество значащих цифр после запятой, а количество значащих цифр всего в записи (причем, значащих цифр двоичных). Вот и получается, что чем число слева от запятой больше, тем точность после запятой меньше (я подразумеваю числа нормализованными).
Ответ написан
hybridcattt
@hybridcattt
Разное кол-во значащих цифр говорит о том, что в 1м случае последняя цифра округлилась до 0.
А вообще, кол-во цифр после запятой не точно — 15-16, у float — 6-7. Это потому, что арифметика на самом деле двоичная, а не десятичная.
Ответ написан
Комментировать
@nerudo
Как вы получили такие результаты?
Функция sqrt() не занимается выводом на экран, она лишь вычисляет выражение. И должна делать это с макимальной доступной [для типа данных] точностью.
Вот я пишу:
> sqrt(2)
ans =
1.4142
А вот:
> fprintf('%.16f\n',sqrt(2))
1.4142135623730951

Matlab 2010b
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы