0

8つの符号なし文字がx1,x2,...x8あり、計算したいとします:

abs((x1 + x2 + x3 + x4) - (x5 + x6 + x7 + x8)) / 4

大きなオーバーフローまたはアンダーフロー エラーを発生させずに、最も正確な結果を保証する最善の方法は何でしょうか?

これをテンプレート クラスで使用しているため、符号なしの値を符号付きの値に変換することはできません。

4

3 に答える 3

7

以上のoperator +場合のみ機能しintます。charしたがって、型(int より小さい) のオブジェクトで使用すると、これらの値は操作が行われる前に自動的に int に変換されます。

したがって

abs((x1 + x2 + x3 + x4) - (x5 + x6 + x7 + x8)) / 4

コンパイラによって次のように変換されます。

abs((static_cast<int>(x1) + static_cast<int>(x2) + static_cast<int>(x3) + static_cast<int>(x4)) - 
    (static_cast<int>(x5) + static_cast<int>(x6) + static_cast<int>(x7) + static_cast<int>(x8))) / 4

したがって、大量の文字を追加しない限り、オーバーフローする可能性は低くなります。

結果を に戻す際に問題がありunsigned charます。式の結果が負の場合、値を正にする変換が行われます (ただし、明確に定義されています)。

于 2013-12-10T21:15:19.220 に答える
1

メタ関数を使用して、計算で使用する中間データ型を伝えたいようです。

    template <class T>
    struct arithmetic_type
    {
        typedef std::int64_t type;
    };

    template <>
    struct arithmetic_type<float>
    {
         typedef double type;
    };

    template <>
    struct arithmetic_type<double>
    {
         typedef double type;
    };

    template <>
    struct arithmetic_type<std::uint64_t>
    {
         typedef std::uint64_t type;
    };

    typedef typename arithmetic_type<T>::type ar_type;
    abs(((ar_type)x1 + x2 + x3 + x4) - ((ar_type)x5 + x6 + x7 + x8)) / 4;

もちろん、必要に応じて専門化を微調整したり、追加/削除したりできますが、これで正しいアイデアが得られるはずです。

于 2013-12-10T21:10:27.493 に答える