2017-04-04 472 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