从double转换为unsigned int时的C ++整数溢出问题

时间:2010-06-25 14:45:22

标签: c++ datetime time casting type-conversion

我需要在C ++中将时间从一种格式转换为另一种格式,并且它必须是跨平台兼容的。我创建了一个结构作为我的时间容器。结构字段也必须是遗留代码指定的unsigned int

struct time{   
unsigned int timeInteger;   
unsigned int timeFraction;
} time1, time2;

数学上转换如下:

time2.timeInteger = time1.timeInteger + 2208988800

time2.timeFraction =(time1.timeFraction * 20e-6)* 2e32

这是我在C ++中的原始代码,但是当我尝试写入二进制文件时,转换的时间与真实数据不匹配。我认为这个问题是由于类型转换错误造成的?此代码将在VS2008中编译并将执行。

void convertTime(){
   time2.timeInteger  = unsigned int(time1.timeInteger + 2209032000);
   time2.timeFraction = unsigned int(double(time1.timeFraction) * double(20e-6)*double(pow(double(2),32)));
}

3 个答案:

答案 0 :(得分:2)

只是一个猜测,但你假设2e32 == 2^32?如果您尝试将结果缩放为32位整数,则此假设是有意义的。实际上2e32 == 2 * 10^32

答案 1 :(得分:1)

略有不相关,我认为您应该重新考虑您的类型设计。你基本上是在谈论两种不同的类型。它们碰巧存储相同的数据,尽管结果不同。

为了最大限度地减少使用中的错误,您应该将它们定义为两个完全不同的类型,它们之间有明确定义的转换。

考虑例如:

struct old_time {
    unsigned int timeInteger;   
    unsigned int timeFraction;
};

struct new_time {
public:
    new_time(unsigned int ti, unsigned int tf) :
        timeInteger(ti), timeFraction(tf) { }

    new_time(new_time const& other) :
        timeInteger(other.timeInteger),
        timeFraction(other.timeFraction) { }

    new_time(old_time const& other) : 
        timeInteger(other.timeInteger + 2209032000U),
        timeFraction(other.timeFraction * conversion_factor) { }

    operator old_time() const {
        old_time other;
        other.timeInteger = timeInteger - 2209032000U;
        other.timeFraction = timeFraction / conversion_factor;
        return other;
    }

private:
    unsigned int timeInteger;   
    unsigned int timeFraction;
};

(编辑:当然,由于下面提到的原因,此代码不起作用。

现在这段代码可以安全无阻地使用:

time_old told; /* initialize … */

time_new tnew = told; // converts old to new format
time_old back = tnew; // … and back.

答案 2 :(得分:0)

问题是(20 ^ -6)*(2 e32)远大于UINT_MAX。也许你的意思是2或32的功率,或UINT_MAX,而不是2e32。

另外,你的第一行是整数,初始值必须小于(2 ^ 32 - 2209032000),并且根据测量的内容,它也可以包围。在我看来,将第一个值设置为long long(通常为64位)并更改为2e32。

如果您无法更改类型,则可能需要将字段存储为double,比如说,然后在使用前转换为unsigned int。