2017-04-04 494 views
1

我试图通过同步时间与服务器来修改第二个(long unsigned n_ticks_per_second)的定义来改进SWRTC。在uint32_t计算中转换为float float

#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浮动才能有一个正确的结果,最终,即到底有 n_ticks_per_sec等于1000。

此代码的输出是:

总漂移秒-60在蜱0

n_ticks_per_second 1000

鉴于代码的输出每秒

漂移没有演员扮演的角色是:

总漂移秒-60每秒

漂移在蜱298054

n_ticks_per_second 299054

+1

备选:'rift_per_sec_TICK =(1LL * total_drift_SEC)/(at_update_posix_time - last_update_posix_time);' – chux

+0

@chux:或:...'(的int64_t)total_drift_SEC ...'只是一些具有较高的排名,然后'uint32_t'签署。 – alk

+0

@alk我喜欢'1LL *'或类似与铸造'1LL *'不会缩小'total_drift_SEC',无论类型如何,但是当'total_drift_SEC'是某种类型的'double'时, 。 – chux

回答

2

此行

drift_per_sec_TICK = total_drift_SEC/(at_update_posix_time - last_update_posix_time); 

由一个32位unsigned int把一个32位的signed int

32位unsigned int的排名靠后是32位signed int

当执行算术运算的“常见算术转换”被施加:

C11 Standard (draft) 6.3.1.8/1

如果具有无符号整数类型的操作数的秩大于或 等于秩的另一个操作数的类型,则带有 有符号整数类型的操作数将转换为无符号整数类型为 的操作数的类型。

所以-60被转换为一个(32位)unsigned int4294967236

这里

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

以下适用(从C标准的如上一段):

如果任一操作数的对应实型是浮点型,则其他 操作数在不改变类型域的情况下被转换为对应的实际类型为float的类型。


不要盲目踏进这些陷阱用gcc编译时都会指定-Wconversion

0

因为与 “整数” 版本total_drift_SEC将变得unsigned所以-60 - >4294967236

4294967236/14410 = 298054 

使用float浮点数将计算:

-60/14410 = 0 

参照c-standard在页面53

6.3.1.8通常的算术转换

1许多运营商意想不到算术类型原因转换和产量结果的操作数在 类型类似的方式。目的是确定操作数 和结果的常见实型。对于指定的操作数,每个操作数都将被转换,而不会将类型为 的域更改为相应的实型是普通实型的类型。除非另有明确说明 ,否则公共实数类型也是相应的实数类型 结果,其类型域是操作数的类型域(如果它们相同) ,否则为复数。这种模式被称为通常的算术转换: [...] 否则,整数提升在两个操作数上执行。然后 以下规则被施加到推动操作数:

  • 如果两个操作数具有相同的类型,则没有进一步转化为所需 。否则,如果两个操作数都具有有符号整数类型或者两个 都具有无符号整数类型,则类型为较小 整数转换等级的操作数将转换为操作数的类型,其排名较高。
  • 否则,如果具有无符号整数类型的操作数秩 大于或等于另一个操作数的类型的秩,然后 用符号整型操作数被转换为 操作数与无符号的类型整数类型。
  • 否则,如果操作数的与符号整型类型可以 代表所有与无符号 整型操作数的类型的值,则与无符号整数类型的操作数是 转换为的类型带有符号整数类型的操作数。
  • 否则,两个操作数都转换为无符号整数类型 ,对应于带有符号整数类型的操作数的类型。

Ephasis矿

+0

谢谢你的回答:) – PaulGWF