在uint32_t计算中转换为float

时间:2017-04-04 12:38:48

标签: c casting arithmetic-expressions int32 uint32

我正在尝试通过与服务器同步时间来修改第二个(长无符号n_ticks_per_second )的定义来改进SWRTC。

#include <stdint.h>
#include <stdio.h>

int main(int argc, char * argv[]){

    int32_t total_drift_SEC;
    int32_t drift_per_sec_TICK;
    uint32_t at_update_posix_time = 1491265740;
    uint32_t posix_time = 1491265680;
    uint32_t last_update_posix_time = 1491251330;
    long unsigned n_ticks_per_sec = 1000;

    total_drift_SEC = (posix_time - at_update_posix_time);
    drift_per_sec_TICK = ((float) total_drift_SEC) / (at_update_posix_time - last_update_posix_time);

    n_ticks_per_sec += drift_per_sec_TICK;

    printf("Total drift sec %d\r\n", total_drift_SEC);
    printf("Drift per sec in ticks %d\r\n", drift_per_sec_TICK);
    printf("n_ticks_per_second %lu\r\n", n_ticks_per_sec);

    return 0;

}

我不明白的是,我需要将 total_drift_SEC 强制转换为 float ,以便最终获得正确的结果,即拥有n_ticks_per_sec最后等于1000

此代码的输出为:

  

总漂移秒-60

     

以0为单位每秒漂移

     

n_ticks_per_second 1000

而没有强制转换的代码的输出是:

  

总漂移秒-60

     

每秒漂移,刻度为298054

     

n_ticks_per_second 299054

2 个答案:

答案 0 :(得分:2)

这一行

drift_per_sec_TICK = total_drift_SEC / (at_update_posix_time - last_update_posix_time);

将32位signed int除以32位unsigned int

32位unsigned int的排名高于32位signed int

在进行算术运算时,会应用“常用算术转换”:

来自C11 Standard (draft) 6.3.1.8/1

  

如果具有无符号整数类型的操作数的等级大于或等于   等于另一个操作数的类型的等级,然后是操作数   有符号整数类型转换为带有unsigned的操作数的类型   整数类型。

因此-60转换为(32位)unsigned int4294967236

下面

drift_per_sec_TICK = (float) total_drift_SEC / (at_update_posix_time - last_update_posix_time);

以下适用(来自上述C标准的段落):

  

如果任一操作数的相应实数类型是float,则另一个   操作数在不更改类型域的情况下转换为其类型的类型   相应的实际类型为float

在使用GCC进行编译时,为了不盲目地进入陷阱,请始终指定-Wconversion

答案 1 :(得分:0)

因为&#34;整数&#34;版本total_drift_SEC将变为unsigned,因此-60 - &gt; 4294967236

4294967236 / 14410 = 298054

使用float,除法将计算:

-60/14410 = 0

请参阅第53页的c-standard

  

6.3.1.8常规算术转换

     

1许多期望算术类型操作数的运算符会导致转换并产生结果   以类似的方式输入类型。目的是确定操作数的通用实数类型   和结果。对于指定的操作数,将转换每个操作数,而不更改类型   域,对应的实类型是常见的实类型。除非   另外明确说明,常见的真实类型也是相应的实际类型   结果,其类型域是操作数的类型域,如果它们是相同的,   否则复杂。这种模式称为通常的算术转换:   [...]   否则,将对两个操作数执行整数提升。那么   以下规则适用于提升的操作数:

     
      
  • 如果两个操作数具有相同的类型,则不再进行进一步的转换   需要。否则,如果两个操作数都有有符号整数类型或两者都有   有无符号整数类型,操作数类型较小   整数转换等级转换为操作数的类型   更高的等级。
  •   
  • 否则,如果具有无符号整数类型的操作数具有等级   那么,大于或等于另一个操作数的类型的等级   带有符号整数类型的操作数转换为   具有无符号整数类型的操作数。
  •   
  • 否则,如果带有符号整数类型的操作数的类型可以   表示带有unsigned的操作数类型的所有值   整数类型,那么带无符号整数类型的操作数是   转换为带有符号整数类型的操作数类型。
  •   
  • 否则,两个操作数都将转换为无符号整数类型   对应于带有符号整数类型的操作数的类型。
  •   

Ephasis mine