Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.03.2014, 21:40   #1
Акоб
Форумчанин
 
Регистрация: 10.01.2011
Сообщений: 243
По умолчанию Дробная часть от float

Здравствуйте, нужно найти те числа из массива, в конце которых цифра 7.
Я пробовал делать так
Код:
#include<iostream>
#include<conio.h>

using namespace std;

int main()
{
	int i,j,c;
    float x[10]={4.1,52.7,3.2,14.040,21.07,52.367,41.21,23.1478547,52.3247,12.21};
	float y[10];
	
	j=0;
	for(  i = 0; i < 10; i++)
	{ 
		c=0;
		while( (x[i] - int(x[i])) != 0)
		{
			x[i] = x[i] * 10;
//     		cout<<x[i]<<" "<<(int)x[i]<<" "<<x[i] - int(x[i])<<" ";
			getch();
			c++;
		}
		cout<<endl;
		
		if ((int)x[i]%100==7)
		{
			y[j]=x[i]/((c-1)*10);
			cout<<y[j]<<endl;
            j++;
		}
	}
	

	return 0;
}
Умножаю переменную типа float на 10 столько раз пока она не станет целым числом. но когда я превращаю float в int, то цифра становится на 1 меньше.
когда x[i] = 52367, int(x[i]) почему-то становиться 52366
В гугле искал, но ничего не нашел. Заранее спасибо.
Акоб вне форума Ответить с цитированием
Старый 10.03.2014, 22:11   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Думаю тебе поможет следующее:
Код:
char c[20]={0};
sprintf(c,"%f",x[i]);
if(c[strlen(c)-1]=='7'){делаем что-то}
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.03.2014, 22:18   #3
Акоб
Форумчанин
 
Регистрация: 10.01.2011
Сообщений: 243
По умолчанию

Твой вариант верен, хотелось бы узнать почему в маем случае не получается, вроде простой алгоритм и вроде бы проблем не должно быть.
Акоб вне форума Ответить с цитированием
Старый 10.03.2014, 22:34   #4
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Думаю тебе поможет следующее:
Код:
char c[20]={0};
sprintf(c,"%f",x[i]);
if(c[strlen(c)-1]=='7'){делаем что-то}
Это через раз не будет работать. Потому что флоты без основания 2 имеют погрешность


http://rextester.com/JZV9205


Код:
#include<iostream>

using namespace std;

int main()
{
    const float f = 52.7;
    char c[20]={0};
    sprintf(c,"%f",f);
       
    cout<<" c = "<<c<<endl;

	return 0;
}

вывод:
Код:
 c = 52.700001
_Bers вне форума Ответить с цитированием
Старый 11.03.2014, 00:00   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Потому что флоты без основания 2 имеют погрешность
Скорректировать на %.2f? Или не решит проблему?
Цитата:
почему в маем случае не получается
Я не отлаживал твой код, так что не в курсе что в нем за проблема )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 11.03.2014, 01:00   #6
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Скорректировать на %.2f? Или не решит проблему?

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

Например:

флотовый 52.7 где то может быть : 52.700001, а где то 52.699999


Поэтому, когда нужно сравнить два флотовых числа, их сравнивают с учетом погрешности:

Код:
const float a = 52.7;
const float b = GetNumber();

if( a-b<= 0.000001)
    cout<<"числа равны"<<endl;
По решению задачи навскидку мне пришел в голову только топорный вариант:

http://rextester.com/ZXY28859


Код:
#include <iostream>
#include <sstream>
using namespace std;

enum { eprecision=6};

void init()
{

    cout.unsetf ( std::ios::floatfield );
    cout.precision(eprecision);
    cout.setf( std::ios::fixed, std:: ios::floatfield ); 

}

bool has_seven(const double v)
{
    stringstream ss; 
    ss.unsetf ( std::ios::floatfield );
    ss.precision(eprecision);
    ss.setf( std::ios::fixed, std:: ios::floatfield ); 
    
    ss<<v;
    string s;
    ss>>s;
    
    if (s.length()==0)
        return false;
    
    while( s.back()=='0' )
        s.pop_back();
    
    return s.back()=='7';
}

   

int main()
{
    init();
    std::cout << "Hello, world!\n";
   
    const double src[]={4.1,52.7,3.2,14.040,21.07,52.367,41.21, 2.478547, 52.3247,12.21, 3.123457};
    for(auto i: src)
        cout << "value = "<< i << " ---> "
             << ( has_seven(i)? "yes!" : "no")
             << endl;
        
}
Он работает только при условии, что количество значащих цифр не превышает 7. И тип данных - double.

Для float количество значащих цифр будет меньше.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дробная часть числа Иллидан Общие вопросы C/C++ 11 31.05.2011 16:23
Целая и дробная часть от деления Anubys Помощь студентам 5 29.04.2011 22:11
как получить дробную часть float ]tach[ C++ Builder 6 23.01.2011 15:57
Дробная часть в fstream Ozerich Общие вопросы C/C++ 3 14.03.2009 23:00
Машина Тьюринга (дробная часть от деления) o1ps Свободное общение 0 03.12.2007 14:02