LINUX.ORG.RU

modf, результат умножаешь на 10^n, приводишь к int

lester ★★★★
()

WARNING - БЫДЛОКОД

#include <stdio.h>
#include <QString>

int main(int argc, char *argv[])
{
	float x = 345.45654;
	QString x_str = QString::number(x, 'f', 5);
	x_str = x_str.right(x_str.length() - x_str.indexOf('.') - 1);
	int y = x_str.toInt();
	printf("%d\n",y);
}

Starting /tmp/t/t...

45654

/tmp/t/t exited with code 0

bk_ ★★
()
Ответ на: комментарий от lester

Когда писал, тоже вспомнил об этом, но это уже мелочи.

bk_ ★★
()

Рабочий вариант

#include <stdio.h>
#if defined(BYDLOCODE)
#include <QString>
#else
#include <math.h>
#endif

int main(int argc, char *argv[])
{
	double x = 345.45654;
#if defined(BYDLOCODE)
	QString x_str = QString::number(x, 'f', 5);
	x_str = x_str.right(x_str.length() - x_str.indexOf('.') - 1);
	int y = x_str.toInt();
	printf("%d\n",y);
#else
	double int_part, fract_part;
	fract_part = modf(x, &int_part);
	do {
		fract_part *= 10;
	} while ((fract_part - (double)((int)fract_part)) > 0.01);

	printf("%d\n", (int)fract_part);
#endif
}
bk_ ★★
()
Ответ на: Рабочий вариант от bk_

Кстати, второй вариант хреново работает с «разряженными» дробными числами. По идее, там надо вместо > 0.01 написать > 0.000001 - то есть предел точности.

Самое интересное, что первый вариант работает безошибочно. Я бы использовал инрл именно его.

bk_ ★★
()
Ответ на: комментарий от annoynimous

А по моему задача абсолютно корректна. Поэтому первый вариант с преобразованием в строку уходит от вашей проблемы с представлением.

Тем паче, если я не ошибаюсь, дробные числа в памяти компа рационализируются. Поэтому разночтений быть не может.

bk_ ★★
()
Ответ на: комментарий от amonymous

> В QString же все насильно в utf8 приводит не?

utf8 это в чем хранятся строки в текущей локали, а есть еще денежные единицы, разделители и пр.

lester ★★★★
()
Ответ на: комментарий от lester

Короче, вот реально работающий код

#include <stdio.h>
#include <QString>
#include <math.h>

int main()
{
	double x = 345.40207;
	double int_part, fract_part;
	fract_part = modf(x, &int_part);
	QString x_str = QString::number(fract_part, 'f');
	while (x_str[x_str.length() - 1] == '0') {
		x_str = x_str.left(x_str.length() - 1);
	}
	x_str = x_str.right(x_str.length() - 2);
	int y = x_str.toInt();
	printf("%d\n",y);
}
bk_ ★★
()
Ответ на: Короче, вот реально работающий код от bk_

вот только смысла принципиального нет хранить дробную часть в int без указания точности - их и не сравнить, и не использовать в выражении, а так обычный int( 10000. * x ) % 10000 будет во много раз быстрей

lester ★★★★
()
Ответ на: комментарий от lester

Согласен, но если стоит задача выделить дробную часть, то только так. Откуда я могу знать, сколько там знаков после запятой?

Если сделать int( 10000. * x ) % 10000 - а вдруг там 2 знака после запятой? У вас получится чушь.

И вообще я не понимаю, где может понадобиться выделение дробной части как целой.

bk_ ★★
()
Ответ на: комментарий от bk_

> а вдруг там 2 знака после запятой? У вас получится чушь.

нет - получится значение, которое можно и сравнить и сплюсовать и т.п.

lester ★★★★
()
Ответ на: комментарий от lester

Это так, если ТСу требуется выполнять какие-то относительные действия, а если просто, то только кодом выше.

aihas, все зависит от постановки задачи.

bk_ ★★
()
Ответ на: комментарий от xydo

Как ты себе представляешь тысячный, или миллионный интеджер?

amonymous
() автор топика

смотреть до просветления

/usr/include/ieee754.h

а дальше только битовые операции (сдвиги) с целыми числами

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.