Перейти к содержанию
    

IAR 4.40A

Приветствую, господа!

Есть типа код:

double x,x1;
x=1.09; // На самом деле результат вычилений 1.[09]
x1=.09; // аналогично, 0.[09]
x-=x1; // ожидаемо, 1
sprintf(s,"%g",x-1.0); // Вот и проблема! -1.11022е-16

У кого есть идеи, как побороть? Пробовал в другом компилере, результат, ессно, 0. Более того, эти же данные (в сыром виде) передаются на комп, там по той же формуле из тех же данных идет вычисление, и получается 0.

 

Компилер менять не тема - много переносить, и слишком много использовано особенностей данной версии.

 

Исходные данные: IAR 4.40A (4.42A), AT91SAM7X256 (ARM7), CPP.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну а собственно что вас удивляет? Произвольная десятичная дробь в двоичном виде непредставима, отсюда все эти проблемы.

 

x=1.09; // На самом деле результат вычилений 1.[09]
x1=.09; // аналогично, 0.[09]
x-=x1; //[b] это ожидаемо не равно 1[/b]

 

Как вариант - ограничьте точность при выводе - по идее должно помочь ("%.2g" если я правильно помню)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"%.14g"? Не помогает.

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

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь идет вычисление погрешности измерений.

А поподробнее?

Пока что всё выглядит так, будто вы открыли для себя погрешности округления при вычислениях с плавающей точкой. На нобелевку точно не тянет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

double x,x1;
x=1092/1001; // Оба числа целые и результаты измерения входного сигнала
x1=1/11; // Константы, указывающие на приращение по отношению измерения 1092
x-=x1; // Исключаем из измерения результат приращения измерения, являющийся погрешностью
sprintf(s,"%.14g",x-1.0); // здесь выводим абсолютную погрешность измерений, которая не должна быть больше 1 (-1)

На каждую строку специально делал вывод значений, всё вычислялось верно. А вот когда делаю -1, то видим -1.11022е-16.

 

Вроде куда уж подробнее...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот когда делаю -1, то видим -1.11022е-16.

И что? Где проблема? Ожидаемая погрешность, если она отлична от нуля, будет гораздо больше. Следовательно, вот эти малые числа порядка 10^-16 следует считать строго нулём для ваших целей. Короче, ограничивайте точность при выводе результата, как вам и советовали выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И что? Где проблема? Ожидаемая погрешность, если она отлична от нуля, будет гораздо больше. Следовательно, вот эти малые числа порядка 10^-16 следует считать строго нулём для ваших целей. Короче, ограничивайте точность при выводе результата, как вам и советовали выше.

Чуть выше видно, что она есть. Более того, как объяснить, что с теми же данными по таким же формулам ББ считает верно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чуть выше видно, что она есть. Более того, как объяснить, что с теми же данными по таким же формулам ББ считает верно?

А кто такой ББ? Борис Борисыч?

Несмотря на то, что есть стандарт IEEE 754 для вычислений с плавающей точкой, там есть ещё разные режимы округления. Не говоря уже о 80-битовом представлении. Поэтому надо ещё разбираться, чем могут отличаться разные среды вычислений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

double x,x1;
x=1092/1001; // Оба числа целые и результаты измерения входного сигнала
x1=1/11; // Константы, указывающие на приращение по отношению измерения 1092
x-=x1; // Исключаем из измерения результат приращения измерения, являющийся погрешностью 
sprintf(s,"%.14g",x-1.0); // здесь выводим абсолютную погрешность измерений, которая не должна быть больше 1 (-1)

 

 

Вы почитайте все ж что такое числа с плавающей точкой в двоичном представлении. У вас есть примерное представление 1092/1001 и такое же примерное представление 1/11. Более того, точность представления 1/11 больше, чем точность представления 1092/1001. Их разность может получиться чуть меньше или чуть больше единицы. У вас получается чуть меньше

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чуть выше видно, что она есть.

Я не увидел.

Вот это "x-=x1; // ожидаемо, 1" - чем вы смотрели? Уверен, что если вывести эту единицу без ограничения точности, там будет 0,999999999999999.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ББ - Большой Брат. Комп то есть.

Ок, я был не прав, дьявол кроется в деталях. Похоже, что хардварный калькулятор в ББ работает иначе, как впрочем и софтварный в IAR 7.5. То есть для данной точности в 4.40 он то, что считает слишком малым числом, оставляет хвостом, а остальные его отбрасывают. Поэтому получаем не ровно 1, а 1.[куча нолей]9. Вот оттуда и минус...

Кто же знал про такие особенности...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...