外部ライブラリ(ブーストなど)を使わずにstd :: bitset <>をダブルに変換する方法はありますか?私は遺伝的アルゴリズムでゲノムを表現するためにビットセットを使用しています。ビットのセットをダブルに変換する方法が必要です。std :: bitset <64>をダブルに変換するにはどうすればいいですか?
答えて
であるように、C++ 11の道:
union Converter { uint64_t i; double d; };
double convert(std::bitset<64> const& bs) {
Converter c;
c.i = bs.to_ullong();
return c.d;
}
EDIT:コメントで述べたように、それは代わりに、未定義であることの指定されていないとして、我々はchar*
エイリアシングを使用することができます。
double convert(std::bitset<64> const& bs) {
static_assert(sizeof(uint64_t) == sizeof(double), "Cannot use this!");
uint64_t const u = bs.to_ullong();
double d;
// Aliases to `char*` are explicitly allowed in the Standard (and only them)
char const* cu = reinterpret_cast<char const*>(&u);
char* cd = reinterpret_cast<char*>(&d);
// Copy the bitwise representation from u to d
memcpy(cd, cu, sizeof(u));
return d;
}
to_ullong
には、C++ 11がまだ必要です。
はこのUBではありませんか?ユニオンには、一度に1人のメンバーしか含めることができません。 'd'を起動すると' i'が無効になります。 http://stackoverflow.com/q/10271929/1025391 – moooeeeep
も参照してください。http://stackoverflow.com/questions/6136010/is-using-an-union-in-place-of-a-cast-well-defined 。はい、これはUBですが、これはほとんどのプラットフォームで動作します。あなたはそれに頼りたいですか?誰も答えることのできない質問です。 – PlasmaHH
いいですね。確かに非常に滑らか。 –
編集::私はこれで少しばかげていると判断しました。あなたが二重で終わる間、それはビットセットが整数を保持すると仮定します...これは大きな前提です。ビットセットごとに予測可能で反復可能な値になりますが、これは著者が意図したものではないと思います。まあ
あなたはビット値を反復して働くだろう
output_double += pow(2, 64-(bit_position+1)) * bit_value;
をすれば。限り、それはビッグエンディアン
私はここで '^'は力の演算子でなければならないと思いますか?それはC + +では動作しませんが(代わりにビットシフトを使うことができます)、アルゴリズムも間違っています。 –
アルゴの何が間違っているかを把握しようとしています。私は^を変更しました。...疑似コードで始まりました。投稿前に編集するのを忘れました。編集:アルゴリズムの問題を見つけることができません。 – Dennis
'pow'は浮動小数点で動作するので遅すぎます。あなたのアルゴリズムはIEEE形式の 'double'ではなく、整数を変換します。 –
ほとんどの人は、エンコードされたintまたはdoubleを直接含んでいるかのようにビットベクトルを処理できるようにするための答えを提供しようとしています。
私はこのアプローチを完全に避けることをお勧めします。作業の定義のために「機能する」とはいえ、どこにでもハミング・クリフが導入されています。 2つのデコードされた値がお互いに近い場合、それらのエンコードされた値がお互いに近くなるようにエンコードすることが通常はエンコードするようにします。また、64ビットの精度を使用する必要があります。
私は手動で変換を管理します。エンコードする変数x、y、zが3つあるとします。あなたのドメインの専門知識は、例えば、-= x < 5,0 0 < = y < 100、および0 < = z < 1であり、xの精度は8ビット、yのビットは12ビット、およびzについては10ビットである。これはわずか30ビットの合計検索スペースを提供します。最初の8文字をx、次の12文字をy、最後の10文字をzとして扱うことができます。あなたはハミング崖を取り除くために、それぞれをグレイコードで自由にすることもできます。
私は個人的には過去に次のことをやった:
inline void binary_encoding::encode(const vector<double>& params)
{
unsigned int start=0;
for(unsigned int param=0; param<params.size(); ++param) {
// m_bpp[i] = number of bits in encoding of parameter i
unsigned int num_bits = m_bpp[param];
// map the double onto the appropriate integer range
// m_range[i] is a pair of (min, max) values for ith parameter
pair<double,double> prange=m_range[param];
double range=prange.second-prange.first;
double max_bit_val=pow(2.0,static_cast<double>(num_bits))-1;
int int_val=static_cast<int>((params[param]-prange.first)*max_bit_val/range+0.5);
// convert the integer to binary
vector<int> result(m_bpp[param]);
for(unsigned int b=0; b<num_bits; ++b) {
result[b]=int_val%2;
int_val/=2;
}
if(m_gray) {
for(unsigned int b=0; b<num_bits-1; ++b) {
result[b]=!(result[b]==result[b+1]);
}
}
// insert the bits into the correct spot in the encoding
copy(result.begin(),result.end(),m_genotype.begin()+start);
start+=num_bits;
}
}
inline void binary_encoding::decode()
{
unsigned int start = 0;
// for each parameter
for(unsigned int param=0; param<m_bpp.size(); param++) {
unsigned int num_bits = m_bpp[param];
unsigned int intval = 0;
if(m_gray) {
// convert from gray to binary
vector<int> binary(num_bits);
binary[num_bits-1] = m_genotype[start+num_bits-1];
intval = binary[num_bits-1];
for(int i=num_bits-2; i>=0; i--) {
binary[i] = !(binary[i+1] == m_genotype[start+i]);
intval += intval + binary[i];
}
}
else {
// convert from binary encoding to integer
for(int i=num_bits-1; i>=0; i--) {
intval += intval + m_genotype[start+i];
}
}
// convert from integer to double in the appropriate range
pair<double,double> prange = m_range[param];
double range = prange.second - prange.first;
double m = range/(pow(2.0,double(num_bits)) - 1.0);
// m_phenotype is a vector<double> containing all the decoded parameters
m_phenotype[param] = m * double(intval) + prange.first;
start += num_bits;
}
}
なお、おそらく私がビットベクトルを使用していなかった、あなたに関係ない理由のために - 普通vector<int>
へ物事をエンコードする。もちろん、このコードにはたくさんのものがありますが、ここには載っていませんが、おそらく基本的な考えを得ることができます。
GPUの計算を行っている場合や、64ビットが適切なサイズになっているような特定の問題がある場合は、すべてをネイティブワードに埋め込む余計なオーバーヘッドになる可能性があります。それ以外の場合は、検索プロセスに追加するオーバーヘッドが、エンコードとデコードの高速化によって得られるメリットを圧倒していると思います。
- 1. std :: vector <float>をfloat配列に変換するにはどうすればよいですか?
- 2. UTF-8 std :: stringをUTF-16 std :: wstringに変換するにはどうすればよいですか?
- 3. ダブルGET変数を持つ配列を作成するにはどうすればいいですか
- 4. 分数エポックタイムスタンプ(ダブル)をstd :: chrono :: time_pointに変換するには?
- 5. URLをcodeigniterに変換するにはどうすればいいですか?
- 6. UIWebViewをビットマップに変換するにはどうすればいいですか?
- 7. Some( "")をNoneに変換するにはどうすればいいですか?
- 8. FlowDocumentをPDFに変換するにはどうすればいいですか
- 9. DFAをチューリングマシンに変換するにはどうすればいいですか?
- 10. DBQuery <T>をObjectQuery <T>に変換するにはどうすればよいですか?
- 11. このIQueryable <Patient>をDbSet <Patient>に変換するにはどうすればよいですか?
- 12. リスト<string>をchar **に変換するにはどうすればよいですか?
- 13. 変換演算子でstd :: enable_ifを使用するにはどうすればよいですか?
- 14. <このブックマークレット>をフォームに変換するにはどうすればいいですか?
- 15. std :: wstring _TCHAR []から変換するにはどうすればよいですか?
- 16. C++でビットセットをshortに変換するにはどうすればよいですか?
- 17. boost :: bimapでstd :: for_eachを使うにはどうすればいいですか?
- 18. wchar_t *をwstringに変換するにはどうすればよいですか?
- 19. オーディオをテキストに変換するにはどうすればよいですか?
- 20. ソフトウェアアプリケーションをソフトウェアアプライアンスに変換するにはどうすればよいですか?
- 21. JSONArrayをJSONObjectに変換するにはどうすればよいですか?
- 22. byte []をBitmapに変換するにはどうすればよいですか?
- 23. SqlXmlをXmlTextに変換するにはどうすればよいですか?
- 24. LFをCRLFに変換するにはどうすればよいですか?
- 25. ハッシュタグテキストをハッシュタグハイパーリンクに変換するにはどうすればよいですか?
- 26. UTCをDateTimeに変換するにはどうすればよいですか?
- 27. string []をArrayListに変換するにはどうすればよいですか?
- 28. NSStringをNSDateに変換するにはどうすればよいですか?
- 29. Lucene.Net:MultiFiledQueryParserをBooleanQueryに変換するにはどうすればよいですか?
- 30. System.TypeをUriに変換するにはどうすればよいですか?
ビットが64ビット整数を表し、それをダブルに変換しますか?(ビットを倍精度浮動小数点数のバイナリ表現として扱うのとは対照的に)。 –
'* reinterpret_cast(&bitset <64> :: to_ullong())'を使用していませんか? –
user2k5
@ user2k5:これは、互換性のないポインタ型を使ってオブジェクトをデリファレンスしています...私はC++のルールが何であるか分かりませんが、そのアクションはCの未定義の動作です。 – dreamlax