2016-06-01 18 views
4

正規化された整数値を実際の浮動小数点値に変換する必要があります。たとえば、int16_tの場合、1.0の値は32767で表され、-1.0は-32768で表されます。符号付きと符号なしの両方の整数型ごとにこれを行うのはちょっと面倒ですが、手書きで書くのはまだ簡単です。正規化された整数からフロートへの変換

しかし、標準的な方法を使用するのではなく、ホイールを改造して再開発するのではなく、標準のCまたはC++ヘッダ、Boostライブラリ、またはその他の小型でポータブルなものこれらの変換をすでに実行している簡単に組み込まれたソースです。

+1

に正規化しライブラリが必要であることを確かめてください... 'double convert(int16_t x){return x <0? x/double(32768):x/double(32767);} ' 'std :: numeric_limits'を使って簡単にすべてのint型にテンプレート化して一般化することができます。とにかくそれは非常に短く、確かに標準ライブラリにはありません。こちらもご覧ください:http://stackoverflow.com/questions/929103/convert-a-number-range-to-another-range-maintaining-ratio – coyotte508

+1

@ coyotte508私はまだそれを見つけられませんでしたが、私は本当に見ていた/標準ライブラリのstd :: numeric_limitsのように既にテンプレート化されていることを期待しています。これは、私がこれを必要とする唯一の人ではないことを知っているからです。私は自分のキャリアを書くのに費やしたことは、すでに標準化されているはずですが、最近、自分自身で書く前に、既存の標準化されたコードを見つけようとしていることを、ところで、リンクをありがとう。 – IntellectualKitty

+1

私は通常は同意しますが、それが1行であれば、わかりやすく標準的な名前の関数呼び出しで囲まれているよりも "インライン"(現場)であることが明確です。ちなみに、質問に直角に、あなたはフロートを使いたいですか?精度は0から1までの範囲で非常に異なります。 –

答えて

6

ここstd::numeric_limitsを使用してテンプレート化ソリューションです:

#include <cstdint> 
#include <limits> 

template <typename T> 
constexpr double normalize (T value) { 
    return value < 0 
    ? -static_cast<double>(value)/std::numeric_limits<T>::min() 
    : static_cast<double>(value)/std::numeric_limits<T>::max() 
    ; 
} 

int main() { 
    // Test cases evaluated at compile time. 
    static_assert(normalize(int16_t(32767)) == 1, ""); 
    static_assert(normalize(int16_t(0)) == 0, ""); 
    static_assert(normalize(int16_t(-32768)) == -1, ""); 
    static_assert(normalize(int16_t(-16384)) == -0.5, ""); 
    static_assert(normalize(uint16_t(65535)) == 1, ""); 
    static_assert(normalize(uint16_t(0)) == 0, ""); 
} 

これは、両方の符号付きと符号なし整数を処理し、0は私はありません0

View Successful Compilation Result

+1

これは非常にいいコードであり、良い使用例のテストです。ありがとうございました。 – IntellectualKitty

+1

整数から倍精度への変換は簡単ですが、2倍から整数への正しい解を見ることもできます(つまり、0.99999999999 == 32766ではなく、0.99999999999 == 32767となります)。 static_castのこの方向の同様のアプローチは、static_castがラウンドではなく切り詰める方法のために、(value * std :: numeric_limits :: max() 'のようなアプローチです。 –

-2

それは両方 は、符号付きと符号なし、各整数型のためにこれを行うには少し面倒ですが、それはまだ手で書くことは十分に簡単です。

整数型ごとにこれを行う必要はありません。代わりに<limits>を使用してください。

template<class T> double AsDouble(const T x) { 
    const double valMin = std::numeric_limits<T>::min(); 
    const double valMax = std::numeric_limits<T>::max(); 
    return 2 * (x - valMin)/(valMax - valMin) - 1; // note: 0 does not become 0. 
} 
関連する問題