2017-04-04 87 views
1

時間をサーバと同期させて秒の定義(長い符号なしn_ticks_per_second)を変更してSWRTCを改善しようとしています。uint32_t計算で浮動小数点数に変換する

#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をキャストする必要があるということです

すなわちエンドで1000 n_ticks_per_sec等しいを持っています。

このコードの出力である:

総ドリフト秒-60秒当たり

ドリフトでは、コードの出力に対し0

n_ticks_per_second千

をマダニキャストを浮かべることなく:

総ドリフト秒-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 int

:ここ

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

以下が(上記のようにCの標準の段落から)適用4294967236

いずれかのオペランドの対応する実タイプが浮動小数点である場合は、もう一方は オペランドは、タイプドメインを変更することなく、 に対応する実タイプがfloatのタイプに変換されます。


盲目的GCCでコンパイルするときは、常に-Wconversionを指定し、そのトラップに乗らないために。

0

をティックにtotal_drift_SECになるであろうunsignedので-60 - >4294967236

4294967236/14410 = 298054 

floatを使用すると、除算が計算されます。

-60/14410 = 0 

6.3.1.8通常の算術変換 タイプの演算式原因変換および収量結果のオペランドを期待

1多くのオペレータページでc-standardを参照同様の方法。目的は、オペランド と結果の共通の実数型を決定することです。指定されたオペランドについては、各オペランドは、タイプ ドメインの変更なしに、対応する実タイプが共通の実タイプであるタイプに変換されます。 に明示的に別途明記されていない限り、共通実数型は対応する実数型 であり、型ドメインは被演算子の型ドメインである場合は同じ とそれ以外の複合型です。このパターンを通常の算術変換と呼びます。 [...] それ以外の場合、整数の昇格は両方のオペランドで実行されます。その後 次の規則が促進オペランドに適用されます。

  • 両方のオペランドが同じ型を持っている場合は、それ以上の変換が必要な ではありません。そうでない場合、両方のオペランドが符号付き整数型を持つか、または両方とも符号なし整数型を持つ場合、 より小さい型のオペランドは、 上位ランクのオペランドの型に変換されます。符号なし整数型を持つオペランドがランク大きいかまたは他のオペランドのタイプのランクに等しい を有する場合
  • そうでない場合、次いで、符号付き整数型を持つオペランドは、符号なしと オペランドの型に変換され 整数型。そうでない場合
  • 、符号付き整数型を持つオペランドの型は、次に符号なし整数型を持つオペランドがタイプに 変換され、符号なし 整数型とオペランドの型の値の全てを 表すことができる場合符号付き整数型のオペランド
  • それ以外の場合は、両方のオペランドが符号付き整数型のオペランドの型に対応する符号なし整数型 に変換されます。

Ephasis鉱山

+0

ありがとうございます:) – PaulGWF

関連する問題