Russian Qt Forum

Программирование => С/C++ => Тема начата: Даниил от Февраль 25, 2012, 04:54



Название: Что за странный глюк
Отправлено: Даниил от Февраль 25, 2012, 04:54
Приветствую всех.
Писал очередную курсовую и возникли траблы с округлением чисел. Конкретно.
Код
C++ (Qt)
#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;
 
class testClass{
private:
   float var;
   int acc;
public:
   testClass(float _var = 0.0, int _acc = 0){var = _var; acc = _acc;}
   void roundVar();
};
 
void testClass::roundVar()
{
   float temp = var;
   int i = 0;
   while(i < acc){
       if((temp - floor(temp)) == 0){
           cout << i << " : " << temp <<" Number is integer!" << endl;
           break;
       }
       else{
           cout << i << " : " << temp - floor(temp) << endl;
           temp = temp - floor(temp);
           temp *= 10;
           i++;
       }
   }
}
 
int main()
{
   testClass a(3.14, 2);
   a.roundVar();
   getchar();
 
   return 0;
}
 
По идее, код должен выводить дробную часть числа, отрезая на каждом шаге старший разряд. Но, вывод представляет собой нечто оригинальное:
Код:
0 : 0.14
1 : 0.400001
Если кто-то сможет дать пояснения, где подвох - буду премного благодарен.


Название: Re: Что за странный глюк
Отправлено: Blackwanderer от Февраль 25, 2012, 06:51
Что написали, то и получили
Шаг первый:
Код
C++ (Qt)
// temp=3.14
// floor(temp) = 3
temp = temp - floor(temp);
// temp=0.14
temp *= 10;
// temp=1.4
 
Шаг второй:
Код
C++ (Qt)
// temp=1.4
// floor(temp) = 1
temp = temp - floor(temp);
// temp=0.4
 


Название: Re: Что за странный глюк
Отправлено: Igors от Февраль 25, 2012, 11:14
Напомним что floor(-3.14) = -4.0. Поэтому лучше без него
Код
C++ (Qt)
inline qreal MyRound( qreal d, int numDigit, bool truncate = true )
{
qreal intP, mul = pow(10.0, (double) numDigit);
modf(d * mul + (truncate ? 0.0 : 0.5), &intP);
return intP / mul;
}  
 


Название: Re: Что за странный глюк
Отправлено: Даниил от Февраль 25, 2012, 14:30
Что написали, то и получили
Не получаем того, что писали. Прочитайте еще раз вывод.
Напомним что floor(-3.14) = -4.0. Поэтому лучше без него
Спасибо, как работает flloor - помню, не суть важна. Суть - почему вывод дает кривой?!

modf(), кстати тоже беду подобную выдавал.


Название: Re: Что за странный глюк
Отправлено: mutineer от Февраль 25, 2012, 14:34
Что написали, то и получили
Не получаем того, что писали. Прочитайте еще раз вывод.
Напомним что floor(-3.14) = -4.0. Поэтому лучше без него
Спасибо, как работает flloor - помню, не суть важна. Суть - почему вывод дает кривой?!

Что написал, то и получил. Если тебя смущает единица в 0.400001, то так уж работает float


Название: Re: Что за странный глюк
Отправлено: Даниил от Февраль 25, 2012, 14:35
Что написали, то и получили
Не получаем того, что писали. Прочитайте еще раз вывод.
Напомним что floor(-3.14) = -4.0. Поэтому лучше без него
Спасибо, как работает flloor - помню, не суть важна. Суть - почему вывод дает кривой?!

Что написал, то и получил. Если тебя смущает единица в 0.400001, то так уж работает float
Так работает и double. Это закономерность?! т.е. типа все в порядке?


Название: Re: Что за странный глюк
Отправлено: mutineer от Февраль 25, 2012, 14:37
Так работает и double. Это закономерность?! т.е. типа все в порядке?

Да, таковы особенности работы чисел с плавающей запятой на современных архитектурах. подробности подскажет гугл