计时器计时器不正确转换秒数 [英] Chrono Timer Not Converting Seconds Properly

查看:211
本文介绍了计时器计时器不正确转换秒数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有趣的,但奇怪的问题,我的游戏计时器。它似乎毫秒工作正常。但是,当我尝试应用 std :: chrono :: seconds cast时,突然获取 0.000000 浮动。



我的计时器如下:

  #include< ; iostream> 
#include< time.h>
#include< chrono>


class Timer
{
public:

typedef std :: chrono :: high_resolution_clock时间;
typedef std :: chrono :: milliseconds ms; //< - 如果改变为秒,我得到0.00000
typedef std :: chrono :: duration< float> fsec;

std :: chrono :: high_resolution_clock :: time_point m_timestamp;

float currentElapsed;

Timer()
{
m_timestamp = Time :: now();
}

float getTimeElapsed()
{
return currentElapsed;
}

void Tick()
{
currentElapsed = std :: chrono :: duration_cast< ms>(Time :: now() - m_timestamp).count ();
m_timestamp = Time :: now();
}

public:
// Singleton stuff
static Timer * Instance();
static void Create();
};

计时器每帧一次所以,例如我通常每帧大约33ms。 33ms / 1000 = 0.033s 秒,所以应该有足够的位空间。





编辑:对不起,秒,不是毫秒


解决方案

std :: chrono :: seconds 都被指定为具有整数表示(C ++ 11§20.11.2[time.syn])。当您将高分辨率持续时间转换为低分辨率持续时间时,您正在执行带有结果截断的整数除法,例如

 使用命名空间std :: chrono; 
assert(duration_cast< seconds>(milliseconds {999})== seconds {0});

您可以通过在缩放之前切换到浮点表示而不是之后的

  using namespace std :: chrono; 
currentElapsed = duration_cast< duration< float,std :: milli>>(Time :: now() - m_timestamp).count();

在coliru演示



更好的是, store currentElapsed 作为 duration 大小

  class Timer {
typedef std :: chrono :: high_resolution_clock时间;
typedef std :: chrono :: duration< float>持续时间;

Time :: time_point m_timestamp;
duration currentElapsed;

public:
Timer():m_timestamp(Time :: now()){}

duration getTimeElapsed()const {
return currentElapsed;
}

void Tick(){
auto now = Time :: now();
currentElapsed = now - m_timestamp;
m_timestamp = now;
}
};


I am having an interesting, yet strange issue with my game timer. It seems like the milliseconds works just fine. However, when I try to apply the std::chrono::seconds cast I suddenly get 0.000000 when casting to a float.

My timer is as follows:

 #include <iostream>
 #include <time.h>
 #include <chrono>


 class Timer
 {
 public:

     typedef std::chrono::high_resolution_clock Time;
     typedef std::chrono::milliseconds ms; //<--If changed to seconds, I get 0.00000
     typedef std::chrono::duration<float> fsec;

     std::chrono::high_resolution_clock::time_point m_timestamp;

     float currentElapsed;

     Timer()
     {
          m_timestamp = Time::now();
     }

     float getTimeElapsed()
     {
         return currentElapsed;
     }

     void Tick()
     {
         currentElapsed = std::chrono::duration_cast<ms>(Time::now() - m_timestamp).count();
         m_timestamp = Time::now();
     }

 public:
     //Singleton stuff
     static Timer* Instance();
     static void Create();
 };

The timer gets ticked once per frame. So, for instance I normally get about 33ms per frame. 33ms / 1000 = 0.033s seconds so there should be plenty of bit space to hold that.

Any ideas on what maybe going on?

Any help is greatly appreciated!

EDIT: Sorry, Seconds, not Milliseconds

解决方案

std::chrono::seconds et al. are all specified to have integral representations (C++11 §20.11.2 [time.syn]). When you convert a high-resolution duration to a low-resolution duration, you are performing integer division with resulting truncation, e.g,

using namespace std::chrono;
assert(duration_cast<seconds>(milliseconds{999}) == seconds{0});

You can avoid this truncation by switching to a floating point representation before scaling instead of after:

using namespace std::chrono;
currentElapsed = duration_cast<duration<float,std::milli>>(Time::now() - m_timestamp).count();

(Demo at coliru)

Better yet, store currentElapsed as a duration to keep the "units" associated with the magnitude:

class Timer {
    typedef std::chrono::high_resolution_clock Time;
    typedef std::chrono::duration<float> duration;

    Time::time_point m_timestamp;
    duration currentElapsed;

public:
    Timer() : m_timestamp(Time::now()) {}

    duration getTimeElapsed() const {
        return currentElapsed;
    }

    void Tick() {
        auto now = Time::now();
        currentElapsed = now - m_timestamp;
        m_timestamp = now;
    }
};

这篇关于计时器计时器不正确转换秒数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆