Вопросы связанные с типом "double"
От: esud http://esud.info
Дата: 01.05.18 01:59
Оценка:
Добрый день! Я сейчас изучаю язык C и столкнулся с вещами, которые на первый взгляд нелогичны.
Смотрите вопросы в коде с примерами:

#include <stdio.h>
#include <float.h>
int main(int argc, char *argv[])
{
    double x = 999999999999999.99;
    printf("%.2lf\n", x); //почему здесь вывод будет "1000000000000000.00" а не "999999999999999.99"?

    x = DBL_MAX;
    x = x - 1;
    if(DBL_MAX == x) {printf("DBL_MAX == DBL_MAX - 1\n");} //почему программа отображает эту строчку?

    x = 999999999999.12;
    printf("%lf\n", x); //почему здесь выводится "999999999999.119995" а не "999999999999.12"?
}


Буду благодарен если кто-то из профессионалов даст ответы на данные вопросы.
esud.info
Re: Вопросы связанные с типом "double"
От: Stanislav V. Zudin Россия  
Дата: 01.05.18 06:36
Оценка: +1
Здравствуйте, esud, Вы писали:

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


Это особенность представления чисел с плавающей точкой.
Можно начать изучение с Вики.
_____________________
С уважением,
Stanislav V. Zudin
Re: Вопросы связанные с типом "double"
От: Анатолий Широков СССР  
Дата: 01.05.18 07:00
Оценка:
Здравствуйте, esud, Вы писали:

E>Буду благодарен если кто-то из профессионалов даст ответы на данные вопросы.


Потому что только часть множества вещественных чисел точно представима фиксированным числом разрядом. Сам посуди, даже отрезок числовой прямой [0, 1] содержит бесконечное множество вещественных чисел. Как ты их будешь представлять фиксированным числом разрядом?
Re: Вопросы связанные с типом "double"
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 01.05.18 07:07
Оценка: 12 (2) +8
Здравствуйте, esud, Вы писали:

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


У этих вопросов вообще-то нет специфики C, есть специфика IEEE754 в частности, и операций с плавающей точкой в целом. Описанные проблемы будут в любом языке, который их использует.

E>Смотрите вопросы в коде с примерами:


E> double x = 999999999999999.99;

E> printf("%.2lf\n", x); //почему здесь вывод будет "1000000000000000.00" а не "999999999999999.99"?

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

E> x = DBL_MAX;

E> x = x — 1;
E> if(DBL_MAX == x) {printf("DBL_MAX == DBL_MAX — 1\n");} //почему программа отображает эту строчку?

Потому что предыдущее значение перед DBL_MAX, которое равно 2^1024-2^971, будет равно 2^1024-2*2^971, разница между ними равна 1.99584030953472e+292. Результат вычитания 1 даст результат, который будет округлён к ближайшему представимому значению, то есть обратно к DBL_MAX. (Знак ^ тут означает возведение в степень.)
Чтобы получить таки отличающееся значение, которое ближайшее к DBL_MAX и меньше его, вызовите nextafter(DBL_MAX, -1).

E> x = 999999999999.12;

E> printf("%lf\n", x); //почему здесь выводится "999999999999.119995" а не "999999999999.12"?

Потому что на самом деле представленное число равно 999999999999.1199951171875 — это точный десятичный перевод того двоичного представления, которое лежит в x после такого присвоения.
Вывод с %lf выводит 6 десятичных разрядов послед занятой, округляя к последнему из них.

E>Буду благодарен если кто-то из профессионалов даст ответы на данные вопросы.


Вам надо внимательно сходить сюда и прочитать:
  • What Every Programmer Should Know About Floating-Point Arithmetic
  • What every computer scientist should know about floating-point (вариация предыдущего)
  • Машинные методы математических вычислений (хотя бы первые главы, где обсуждаются проблемы точности, ситуации катастрофической потери точности и т.п.) (книга есть в pdf в сети, сами найдёте, если что)
  • Все ответы на вопрос, повторы которого задаются новичками каждые три дня, если не чаще.

    За подробность — плюс (обычно новички ограничиваются вопросами типа "какого чёрта 0.1+0.2 != 0.3?"), но ещё есть много чему учиться.
  • The God is real, unless declared integer.
    Отредактировано 01.05.2018 7:10 netch80 . Предыдущая версия .
    Re: Вопросы связанные с типом "double"
    От: Muxa  
    Дата: 01.05.18 19:42
    Оценка: +1
    E>Буду благодарен если кто-то из профессионалов даст ответы на данные вопросы.
    Лабу делаешь?
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.