我正在开发一个具有32位长int的小型嵌入式系统。对于一个计算,我需要以毫秒为单位输出自1970年以来的时间。我可以从1970年以来以32位无符号长秒为单位获得时间,但如果我的最大int只有32位,我如何将其表示为64位的毫秒数?我相信stackoverflow会有一个狡猾的答案!我使用的是动态C,接近标准C。我有一些来自另一个系统的样本代码,它有一个64位长的数据类型:
long long T = (long long)(SampleTime * 1000.0 + 0.5);
data.TimeLower = (unsigned int)(T & 0xffffffff);
data.TimeUpper = (unsigned short)((T >> 32) & 0xffff);
由于您只乘以1000(秒->millis),您可以用两个16位的mutliplies和一个加法以及一点位篡改来完成,因此我使用了您假定的数据类型来存储以下结果:
uint32_t time32 = time();
uint32_t t1 = (time32 & 0xffff) * 1000;
uint32_t t2 = ((time32 >> 16) * 1000) + (t1 >> 16);
data.TimeLower = (uint32_t) ((t2 & 0xffff) << 16) | (t1 & 0xffff);
data.TimeUpper = (uint32_t) (t2 >> 16);
假设有16x16->32乘法可用,标准方法是将两个数字拆分为16位的高和低部分,计算四个偏积,并将结果相加。如果你没有比32x32->32基元更快的16x16->32基元,我不确定最好的方法是什么。我认为32x32->32乘法应该比16x16->32更有用,但我不知道该如何使用它。
就我个人而言,我希望有一个标准的原语来返回NxN乘法的上半部分(当然是32x32;对于较小的机器也是16x16,对于较大的机器是64x64)。
如果你更具体地知道你需要做什么样的计算,这可能会有所帮助。用32位运算实现的64位乘法非常慢,而且你可能会有64位除法的额外开销(转换回秒和毫秒),这甚至更慢。
在不知道具体需要做什么的情况下,在我看来,使用一个结构会更有效,它包含一个32位无符号int表示秒数,一个16位int表示毫秒数("余数")。(或者,如果64位对齐比保存几个字节更重要,则使用32位int表示毫秒。)