LINUX.ORG.RU

Не понятное с mktime()


0

0

Доброе время суток!

Задачка по нахождению точки пересечения и времени. при условии что намм данны координаты координаты начала и конца отрезка пересечения и окружность(центр и радиус).

void diftim(char *Ax, char *Ay, char *Bx, char *By, char *Cx, char *Cy) {
	ifstream in("points.txt");
	char *p;
	int i, j;
	double ab_tm;
	long ac_tm;
	struct tm t_a, t_b, *t_c;
	time_t ta, tb, tc;
	char *tmp, *axy, *bxy, *tm_a, *tm_b, ch;
	mpfr_t ax, ay, bx, by, cx, cy;
	mpfr_t res1, res2, res3;
	mpfr_t ab_len, ac_len;
	mpfr_t ab_ac;
	mpfr_init(res1);
	mpfr_init(res2);
	mpfr_init(res3);
	mpfr_init(ax);
	mpfr_init(ay);
	mpfr_init(bx);
	mpfr_init(by);
	mpfr_init(cx);
	mpfr_init(cy);
	mpfr_init(ab_len);
	mpfr_init(ac_len);
	mpfr_init(ab_ac);

	mpfr_set_str(ax, Ax, 10, GMP_RNDN);
	mpfr_set_str(ay, Ay, 10, GMP_RNDN);
	mpfr_set_str(bx, Bx, 10, GMP_RNDN);
	mpfr_set_str(by, By, 10, GMP_RNDN);
	mpfr_set_str(cx, Cx, 10, GMP_RNDN);
	mpfr_set_str(cy, Cy, 10, GMP_RNDN);

	mpfr_sub(res1, bx, ax, GMP_RNDN);
	mpfr_sub(res2, by, ay, GMP_RNDN);
	mpfr_pow_si(res1,res1,2,GMP_RNDN);
	mpfr_pow_si(res2,res2,2,GMP_RNDN);
	mpfr_add(res3, res1, res2, GMP_RNDN);
	mpfr_sqrt(ab_len, res3, GMP_RNDN);
	mpfr_clear(res1);
	mpfr_clear(res2);
	mpfr_clear(res3);
	mpfr_init(res1);
	mpfr_init(res2);
	mpfr_init(res3);

	mpfr_sub(res1, cx, ax, GMP_RNDN);
	mpfr_sub(res2, cy, ay, GMP_RNDN);
	mpfr_pow_si(res1,res1,2,GMP_RNDN);
	mpfr_pow_si(res2,res2,2,GMP_RNDN);
	mpfr_add(res3, res1, res2, GMP_RNDN);
	mpfr_sqrt(ac_len, res3, GMP_RNDN);
	mpfr_div(ab_ac, ac_len, ab_len, GMP_RNDN);
	mpfr_printf("ac/ab = %Rf\n", ab_ac);

	axy = new char[strlen(Ax)+strlen(Ay)+1];
	tmp = new char[60];
	tm_a = new char[20];
	tm_b = new char[20];
	memset(tm_a, 0, 21);
	memset(tm_b, 0, 21);
	sprintf(axy, "%s %s", Ax, Ay);
	while(!strstr(tmp, axy))
		in.getline(tmp, 60);
	delete[] axy;
	for (i = 0; tmp[i] != ' '; i++);
	for (i++; tmp[i] != ' '; i++);
	for (i++, j = 0; tmp[i] != '\0'; j++, i++)
		tm_a[j] = tmp[i];
	strptime(tm_a, "%d.%m.%Y %H:%M:%S ", &t_a);
	cout << tm_a << endl;
	delete[] tm_a;
	in.getline(tmp, 60);
	for (i = 0; tmp[i] != ' '; i++);
	for (i++; tmp[i] != ' '; i++);
	for (i++, j = 0; tmp[i] != '\0'; j++, i++)
		tm_b[j] = tmp[i];
	delete[] tmp;
	strptime(tm_b, "%d.%m.%Y %H:%M:%S", &t_b);
	cout << tm_b << endl;
	delete[] tm_b;
	ta = mktime(&t_a);
	tb = mktime(&t_b);
	cout << "ta = " << ta << endl;
	cout << "tb = " << tb << endl;
	ab_tm = tb - ta;
	mpfr_clear(res1);
	mpfr_init(res1);
	cout << "ab_tm = " << ab_tm << endl;
	mpfr_mul_si(res1,ab_ac,ab_tm,GMP_RNDN);
	ac_tm = mpfr_get_si(res1,GMP_RNDN);
	mpfr_printf("ac_tm_mpfr = %Rf\n",res1);
	cout << "ac_tm = " << ac_tm << endl;
	tc = ta + ac_tm;
	cout << t_a.tm_sec << ' ';
	t_c = gmtime(&tc);
	cout << t_a.tm_sec << endl;

	mpfr_clear(res1);
	mpfr_clear(res2);
	mpfr_clear(res3);
	mpfr_clear(ax);
	mpfr_clear(ay);
	mpfr_clear(bx);
	mpfr_clear(by);
	mpfr_clear(cx);
	mpfr_clear(cy);
	mpfr_clear(ab_len);
	mpfr_clear(ac_len);
	mpfr_clear(ab_ac);
	in.close();

Проблема в

   ta = mktime(&t_a); 
   tb = mktime(&t_b);
Если запускать прогу несколько раз подряд ничего не меняя то появляються очень странные числа. хотя результат и должен быть допустим 18 секунд, но она может насчитать и 3000 и -2000. не могу понять из-за чего такие числа получаються

Заметил что при ошибочных результатах получаеться

ta = 1269438990

tb = 1269435396

а при нормальных

ta = 1269435390

tb = 1269435396



Последнее исправление: Nikolayi4 (всего исправлений: 1)
Ответ на: комментарий от ananas

На удивление получил следующие:

Если следовать из того что strptime() возвращает указатель на первый символ который не обработан, то если уменьшить его то мы получаем последний который обработали. так для ta - ' ', а для tb - действительно последние число в обработке

Nikolayi4
() автор топика
Ответ на: комментарий от ananas

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

Nikolayi4
() автор топика
Ответ на: комментарий от Nikolayi4

просто добавь -D_XOPEN_SOURCE к флагам gcc

а чтобы понять, для чего это, нужно долго и нужно разбирать хидеры glibc

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

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

Nikolayi4
() автор топика
Ответ на: комментарий от Nikolayi4

С чем это вообще может быть еще связанно что он раз через раз считает нормально? Я вообще что-то себе представить не могу...

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

Я кажется догадываюсь почему, добавь следующее перед вызовами соответствующих mktime:
t_a.tm_isdst = -1;
t_b.tm_isdst = -1;

anonymous
()
Ответ на: комментарий от Nikolayi4

Проблема заключается в том, что strptime не заполняет все поля структуры tm, А поле tm_isdst есть индикатор летнего и зимнего времени (0 или положительное значение или наоборот). Так что если там мусор, а он там и есть, так как они объявлены в стеке и ни чем не инициализированы, то поведение mktime становится непредсказуемым. А при отрицательном значении tm_isdst mktime определяет необходимое на основе временной зоны.

Другими словами man mktime

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