1

私はこの機能を持っています

void prtduration(const FILETIME *ft_start, const FILETIME *ft_end) 
{
    double duration = (ft_end->dwHighDateTime - ft_start->dwHighDateTime) *
        (7 * 60 + 9 + 496e-3)
        + (ft_end->dwLowDateTime - ft_start->dwLowDateTime) / 1e7;
    printf("duration %.1f seconds\n", duration);
    system("pause");
}

コードの次の部分の動作を説明できる人はいますか?

(ft_end->dwHighDateTime - ft_start->dwHighDateTime) *
            (7 * 60 + 9 + 496e-3)
            + (ft_end->dwLowDateTime - ft_start->dwLowDateTime) / 1e7;
4

2 に答える 2

5

わお!なんと難読化されたコードでしょう。単純化してみましょう。

   // Calculate the delta
   FILETIME delta;
   delta.dwHighDateTime = ft_end->dwHighDateTime - ft_start->dwHighDateTime;
   delta.dwLowDateTime = ft_end->dwLowDateTime - ft_start->dwLowDateTime;

   // Convert 100ns units to double seconds.
   double secs = delta.dwHighDateTime * 429.496 + delta.dwLowDateTime/1E7

実際、これは間違っていると思います。そのはず:

  double secs = delta.dwHighDateTime * 429.4967296 + delta.dwLowDateTime/1E7

またはさらに明確に:

  double secs = (delta.dwHighDateTime * 4294967296. + delta.dwLowDateTime)/10E6

何が起こっているかというと、ハイタイムに2**32(100ns 単位に変換してから 100ns で割って秒を与える) を掛けているということです。

の計算が間違っているため、これはまだ間違っていることに注意してくださいdelta(元と同じ方法で)。下位部分の減算がアンダーフローすると、上位部分からの借用に失敗します。Microsoft のドキュメントを参照してください。

FILETIME 構造体の値を加算および減算して相対時間を取得することはお勧めしません。代わりに、ファイル時刻の下位部分と上位部分を ULARGE_INTEGER 構造体にコピーし、QuadPart メンバーで 64 ビット演算を実行して、LowPart メンバーと HighPart メンバーを FILETIME 構造体にコピーする必要があります。

または、実際には、この場合、QuadPart を double に変換して分割するだけです。したがって、最終的には次のようになります。

    ULARGE_INTEGER start,end;
    start.LowPart  = ft_start->dwLowDateTime;
    start.HighPart = ft_start->dwHighDateTime;
    end.LowPart = ft_end->dwLowDateTime;
    end.HighPart = ft_end->dwHighDateTime;

    double duration = (end.QuadPart - start.QuadPart)/1E7;

余談ですが、借用の失敗が発見されなかった理由は、コードが 7 分 9 秒を超える長さを出力するように要求されたことがないためだと思います (または、もしそうであったとしても、誰も結果を注意深く見ていませんでした)。

于 2016-03-16T09:06:43.883 に答える
0

7は、FileTime 変数がその値を変更する頻度に非常に近いです。つまり、7 分 (+-3 またはそれ以上) ごとに 1 に増加します。秒単位の値を取得するために 60 を掛けます。

9 + 496e-3 - 私たちが失っているコンパイル (引き出しの開始からコンソールへの出力まで) を処理する時間は秒です。

本当に、これは非常に悪いコードであり、このように書くべきではありません。

しかし、私は FileTime の作業についてよりよく学ばなければなりませんでした。

回答ありがとうございます。

于 2016-03-16T14:03:56.713 に答える