Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Округление дробных чисел в printf()


Автор: Pete 20.11.2008, 01:11
Код

#include <stdio.h>

int main( void )
{
  printf( "%.2f\n", 3.005 ); // !!!!!!!
  printf( "%.2f\n", 33.005 );
  
  return 0;
}

Output:
3.00
33.01

Код

#include <stdio.h>

int main( void )
{
  printf( "%.2f\n", 3.005f ); // !!!!!!!
  printf( "%.2f\n", 33.005f );
  
  return 0;
}

Output:
3.01
33.01

Что происходит?? smile 

Автор: vinter 20.11.2008, 07:43
Цитата(Pete @  20.11.2008,  02:11 Найти цитируемый пост)
Что происходит??

читай про представление вещественных чисел в компьютере.

Автор: Pete 20.11.2008, 12:43
По-моему, вопрос более конкретный. С чем связана разница поведения? В качестве какого типа трактуется константа без модификатора длины?

Автор: Mayk 20.11.2008, 14:08
Цитата(Pete @  20.11.2008,  16:43 Найти цитируемый пост)
В качестве какого типа трактуется константа без модификатора длины?

в качестве double. 
во-втором случае кстати printf'у тоже передается double(именно поэтому в printf'е не важно - пишется %f или %lf, в отличие от scanf), но double получается посредством расширение float'а который представляет 3.005 фиговее чем double

Автор: Pete 21.11.2008, 00:02
$ man 3 printf
Код

f,F    The double argument is rounded and converted to decimal notation in the style...

Т.е. %f используется для double. Почему же тогда округление производится неправильно?

Цитата
но double получается посредством расширение float'а который представляет 3.005 фиговее чем double

Что значит "фиговее"? Указанная точность влезает в любой встроенный тип с плавающей точкой. А повышающее приведение типов всегда безопасно.

Автор: J0ker 21.11.2008, 00:19
Цитата(Pete @ 21.11.2008,  00:02)
Цитата
но double получается посредством расширение float'а который представляет 3.005 фиговее чем double

Что значит "фиговее"? Указанная точность влезает в любой встроенный тип с плавающей точкой. А повышающее приведение типов всегда безопасно.

а где тут опасность?
было 3.005000000000001
стало 3.00499999999999999999999999999999999999999999

Автор: Mayk 21.11.2008, 11:53
Цитата(Pete @  21.11.2008,  04:02 Найти цитируемый пост)
А повышающее приведение типов всегда безопасно

Осталось лишь понять что ты повысил в случае с 3.005f.
Код

    printf("%.25f %.25f\n",3.005, 3.005f);

3.0049999999999999000000000 3.0050001144409180000000000

Цитата(Pete @  21.11.2008,  04:02 Найти цитируемый пост)

Что значит "фиговее"? Указанная точность влезает в любой встроенный тип с плавающей точкой. А повышающее приведение типов всегда безопасно.

Что значит "указанная точность"?
Было во флоате  3.0050001144409180000000000, стало в дабле 3.0050001144409180000000000. double стерпит.
Хотя 3.0049999999999999000000000 в дабле гораздо ближе к 3.005. 

Автор: Pete 21.11.2008, 17:21
Понял. Всем спасибо!  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)