2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Отсчет времени в С++Builder
Сообщение18.01.2008, 22:04 
Аватара пользователя


02/07/07
163
Харьков
Написал программу в Builderе, которая при её запуске должна отсчитывать время. Но только в ней секунды почему-то текут медленнее, чем должно быть. Может быть, это из-за того,что какое-то время требует выполнение кода. Как сделать так, чтобы время отсчитывалось правильно?
Код:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if(na4alo==1)
{Form1->Hide();
na4alo=0;
}

Timer1->Interval=10;
if(msec<99)
        msec++;
else

{
msec=0;
if(sec<59)
        sec++;
else
{
  sec=0;
  if (min <59)
        min++;
  else
  {
   min=0;
   hour++;
  if(hour<=9)
         Label1->Caption="0"+IntToStr(hour);
  else
         Label1->Caption=IntToStr(hour);

  }
  if(min<=9)
        Label3->Caption="0"+IntToStr(min);
  else
        Label3->Caption=IntToStr(min);


}
if(sec<=9)
        Label5->Caption="0"+IntToStr(sec);
else
        Label5->Caption=IntToStr(sec);


}
if(msec<=9)
        Label7->Caption="0"+IntToStr(msec);
else
        Label7->Caption=IntToStr(msec);

}

 Профиль  
                  
 
 
Сообщение19.01.2008, 13:47 


21/03/06
1545
Москва
Во-первых, у Вас интервал вызова ф-ии таймера 10 мс, а в ф-ии в перемнную msec прибавляется только 1.
Update: только что заметил, что переменная msec растет до 100. Тогда все верно, но старайтесь как-то обозначить этот факт в имени самой перемнной. Например, msec_10 или deca_msec.

Второй недостаток Вашего кода, напрямую связанный с недостатками Buildera заключается в том, что для класса TTimer вовсе не гарантируется вызов ф-ии таймера точно столько раз, сколько произошло событие совпадения счетчика миллисекунд. И чем меньший интервал вы поставите, тем больше будет пропусков вызова ф-ии. 10 мс в большинстве случаев является минимальным значением, при которых кол-во пропусков еще приемлемо.

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

P.S. У вас ужасное форматирование кода. Если Вы уважаете тех, кто его будет читать, форматируйте код правильно!

 Профиль  
                  
 
 
Сообщение20.01.2008, 09:28 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Ваш подход не может быть хорошим по нескольким причинам:

1) Виндузе не гарантирует, что Ваша программа будет вызываться каждые $t$ миллисекунд. У них есть внутренний квант времени, и найти вызов, задающий его, мне не удалось. Более того, не гарантируется, что этот квант не зависит от конфигурации виндузе. Мне приходилось сталкиваться и с квантами 10 мс, и с квантами 15.625 мс Вы можете выставить таймер на любое целое число мс, но вызываться Ваша задача будет по квантам.

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

$\sum:$ Единственный правильный способ делать часы — это организовывать таймер, и спрашивать у виндузе (в обработчике события) текущее время. Если Вас устраивает ошибка порядка кванта — лучше всего использовать GetSystemTimeAsFileTime() Если я не ошибаюсь, это очень быстрая функция, не использующая переход ядро (и переключение контекста). Не смотря на очень высокое разрешение (100 наносекунд) она имеет невысокую точность. Если нужна более высокая точность, можно использовать QueryPerformanceCounter() / QueryPerformanceFrequency(). По-моему, эти функции медленнее (переключаются в ядро), позволяют мерить только интервалы времени, но зато с большой точностью — субмикросекунды. Кроме того, не гарантируется сверхвысокая точность этих часов. В частности, при синхронизации часов PerformanceCounter идут равномерно, а SystemTime — слегка меняется.

Ну а дальше — выбор за Вами.

P.S. Всё это совершенно одинаково во всех средах. Builder здесь — последнее, абсолютно ничего не решающее звено. Всё тоже самое будет в студии…

 Профиль  
                  
 
 
Сообщение21.01.2008, 15:38 
Аватара пользователя


02/07/07
163
Харьков
В моём случае времени насчитывалось где-то в полтора раза меньше, то есть интервал 10мс был неприемлем.
Я изменил интервал на 1000мс. Теперь время считается примерно правильно(хоть я и отказался от вывода на экран миллисекунд, но мне это на самом деле было не обязательно).
Всем большое спасибо! 8-)

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group