INT64型(64ビット)の値を、上位バイトからstd:basic_string<byte>に代入するには?


AG  2012-04-04 18:46:48  No: 73288  IP: 192.*.*.*

VC++ 2005  Windows XPで開発しています。

例えば、以下のようなINT64 testの値がある場合、std:basic_string<byte> strArrayに上位バイトから、
1a, 2b, 3c, ・・・のように代入したいです。

INT64 test = 0x1a2b3c4d5e6f7g8i;
std:basic_string<byte> strArray;

// ここで上位バイトからセットしている。
for( int i = 0; i < sizeof(test); i++ )
{
  char temp = (test >> (8*((sizeof(test)-(i+1)))));
  strArray.push_back( temp );
}


一応、動作はしているのですが、コンパイル時に
">>":シフト数が負の値であるか、大きすぎます。定義されていない動作です
とWarningが出てしまいます。


もっと良い方法があると思うのですが、どなたか教えてください。

編集 削除
επιστημη  URL  2012-04-04 18:58:03  No: 73289  IP: 192.*.*.*

...べつに問題ないよぉな。

#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

int main() {
  unsigned long long test = 0x123456789abcdefLL;
  std:basic_string<unsigned char> strArray;

  // ここで上位バイトからセットしている。
  for( int i = 0; i < sizeof(test); i++ ) {
    unsigned char temp = (test >> (8*((sizeof(test)-(i+1)))));
    strArray.push_back( temp );
  }


  cout << setfill('0') << hex;
  for ( int i = 0; i < strArray.size(); ++i ) {
    cout << setw(2) << static_cast<unsigned>(strArray[i]) << ' ';
  }
}

編集 削除
επιστημη  URL  2012-04-04 20:00:29  No: 73290  IP: 192.*.*.*

下位バイトからpush_backし、最後にreverseすればちょびっと簡単になるかな。

編集 削除
tetrapod  2012-04-05 09:27:22  No: 73291  IP: 192.*.*.*

INT64 だと符号つきなので右シフトすると悲しいことになるかもしれない。
UINT64 にすべきかもしれない。仕様レベルから要検討。

この例の場合 8bit 8個 というのは最初から確定済み事項なので、
ループし push_back するのは不必要に重いんではないかな。
俺なら8個手書きするだろう。

std::basic_string<unsigned char> s(8,0);
s[0]=(unsigned char)(val>>54);
s[1]=(unsigned char)(val>>48);
s[2]=(unsigned char)(val>>40);
s[3]=(unsigned char)(val>>32);
s[4]=(unsigned char)(val>>24);
s[5]=(unsigned char)(val>>16);
s[6]=(unsigned char)(val>>8 );
s[7]=(unsigned char)(val>>0 );

編集 削除
AG  2012-04-05 11:34:01  No: 73292  IP: 192.*.*.*

επιστημη さん、tetrapod さん、ありがとうございます。

>仕様レベルから要検討。
これは問題ありません。

一応、動作はしているのですが、Warningで、
「定義されていない動作です」
と出てしまうため、Safetyなコードなのか懸念しています。

やりたいことは、「64bitのデータを1バイトずつ配列につめたい」のですが、他に良い方法はありませんでしょうか?

編集 削除
tetrapod  2012-04-05 12:28:55  No: 73293  IP: 192.*.*.*

俺のコード問題ない(警告0で通る)と思うのだが?

以下余談
> 64bitのデータを1バイトずつ配列につめたい
endianess がどうでもよいか固定であるか
速度が移植性より優先されるか否か
あたりでコードとしてはぜんぜん違う・・・

配列がいいなら basic_string より vector なのでは?

endianess がどうでもいい+移植性0でよいなら
unsigned char* p=reinterpret_cast<unsigned char*>(&val);
で十分かもしれないし

編集 削除
仲澤@失業者  2012-04-05 13:37:26  No: 73294  IP: 192.*.*.*

次のような考え方もあります。
typedef union u64BIT{
   __int64    m_int64;    // 整数表現
   BYTE       m_Byte[ 8]; // Byteの配列として表現
}u64BIT;
u64BIT  u64bit;
u64bit.m_int64 = Value; //何かの値
//後はu64bit.m_Byte[ n]を好きなように使う。
ary.pushback( u64bit.m_Byte[ 0]);

いきなりSTLにすると、そのコードの無理やり感が
なんかあれですね(笑)。

編集 削除