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"
    От: Stanislav V. Zudin Россия  
    Дата: 01.05.18 06:36
    Оценка: +1
    Здравствуйте, esud, Вы писали:

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


    Это особенность представления чисел с плавающей точкой.
    Можно начать изучение с Вики.
    _____________________
    С уважением,
    Stanislav V. Zudin
    Re: Вопросы связанные с типом "double"
    От: Muxa  
    Дата: 01.05.18 19:42
    Оценка: +1
    E>Буду благодарен если кто-то из профессионалов даст ответы на данные вопросы.
    Лабу делаешь?
    Вопросы связанные с типом "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"
    От: Анатолий Широков СССР  
    Дата: 01.05.18 07:00
    Оценка:
    Здравствуйте, esud, Вы писали:

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


    Потому что только часть множества вещественных чисел точно представима фиксированным числом разрядом. Сам посуди, даже отрезок числовой прямой [0, 1] содержит бесконечное множество вещественных чисел. Как ты их будешь представлять фиксированным числом разрядом?
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.