• ベストアンサー

バイナリーで出てくるデータの変更

計測器からバイナリーで出てくるデータを直し保存したいのですが char data1[2048] 計測器からデータを読み込み data1に入れるプログラム printf("Data read: %s\n", data1); とやると、バイナリデータのため文字化けしてしまいます。 このバイナリデータを呼び出して以下のように変更したいです。 ・11bits 4kWords 11111111111で正の最大値、 10000000000で0、 01111111111で負の最大値(一番左が符号ビット)となるバイナリデータを 01111111111で正の最大値、 00000000000で0、 11111111111で負の最大値と変更する 中心の数1024よりも大きい場合は中心の数を引き、 小さい場合には補数を取るためにー1.0を掛ければいいと思うのですが それをC言語でどのようにやればいいのかわかりません。 C言語にあまり詳しくないのですが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

すみません。やってて気がついたんですが、 最上位ビットが立っている > 10000000000で0、 で、 > -1は00000000001 > -2は00000000010だと考えています。 > (一番左の0がマイナスの符号ビットになっている) > (+1は10000000001) とすると、ビットが全部寝ている '0' はどういうあつかいなんでしょうか? その辺をスルーしてやってみるとこんな感じでしょうか? #include <stdio.h> unsigned int tbl[] = { 0x7ff, /* */ 0x7fe, /* */ 0x401, /* 1 */ 0x400, /* 0 */ 0x0, /* ??? */ 0x1, /* -1 */ 0x2, /* -2 */ 0x3fe, /* */ 0x3ff, /* */ }; int main() { const unsigned int mask = ~(~0 << 11); const unsigned int msb = 1 << 10; int i; for (i=0; i < sizeof tbl / sizeof tbl[0]; i++) { printf("%04x => %d\n", tbl[i], ( ((tbl[i] & mask) == msb) ? 0 :(tbl[i] & msb) ? (tbl[i] & ~msb) :(-tbl[i])) ); } return 0; } 実行結果: 07ff => 1023 07fe => 1022 0401 => 1 0400 => 0 0000 => 0 0001 => -1 0002 => -2 03fe => -1022 03ff => -1023

eakm26
質問者

お礼

確かに、0400が0だと考えると0000が不明ですね。 装置の取扱説明書を見たのですがそこまで詳しく書いていないのでわかりませんでした。 なるほど、このようにすれば結果が出ますね。 条件演算子は使い慣れていなかったので、勉強になりました。 0になる所などは何度か変えて試してみたいと思います。 回答していただき本当にありがとうございました。

その他の回答 (2)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

if ( ( c & 0x3ff ) == 0x400 ) {   // 正またはゼロ   c &= 0x3ff; } else {   // 負   c |= 0x400; } ってことでしょうか …

eakm26
質問者

お礼

返信が遅れてしまい大変申し訳ありませんでした。 c&0x3ffはcの第11ビットを0にするだけなので =0x400にはならないと思うのですが違うのでしょうか。 ただ、どのようにやればよいか大変参考になりました。 本当にありがとうございます。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

下駄ばき(バイアス)表現かと思ったら微妙に違いますね。 ・11bits 4kWords 11111111111で正の最大値、 10000000000で0、 01111111111で負の最大値(一番左が符号ビット)となるバイナリデータを 負の最大値(絶対値が最大ということですよね?)は 0 ではなくて、 01111111111 で間違いないですか? そして -1とか-2はどういうパターンになりますか? #00...001 と 00...010 かなあ

eakm26
質問者

補足

返信が遅れてしまって大変申し訳ありませんでした。 負の最大値は絶対値が最大ということです。 わかりにくくてすいませんでした。 -1は00000000001 -2は00000000010だと考えています。 (一番左の0がマイナスの符号ビットになっている) (+1は10000000001)

関連するQ&A

  • バイナリ読み込みについて

    お世話になります。バイナリファイルの読み込みについて質問させてください。 バイナリファイルはC#で出力したものでushort型(符号無し16bit)で書き込んでいます。 //C#でushort型データのバイナリ書き込み例 private static void WriteBinary(){  ushort data=5000;   BinaryWriter bw = new BinaryWriter(new FileStream(@"C:\Binary.txt", FileMode.Create, FileAccess.Write)); bw.Write(data); bw.Close(); } これをJavaで読んで、書き込んだ値5000を取得したいのですが、 C#のushortは符号無しの2Byteなんので、Javaでそれに相当するように readUnsignedShortで読み込んだのですがうまくいきません。どなたかご教授ください。 //Javaでushort型データのバイナリ読み込み private static void ReadBinary(){  DataInputStream dis = new DataInputStream(new FileInputStream("C:\\Binary.txt"));  int data = dis.readUnsignedShort();  System.out.println(data);  } すると「34835」と表示されます。その他、readShort()→-30701 read(byte[2])として byteに格納してbyte[0]と[1]を足しても-101になり取得できませんでした。 保存されたデータは符号なしの16ビットなのでreadUnsignedShort()で取得できると 思ったのですが、何か根本的に考え方が違うのでしょうか?? ※もちろんC#でReadInt16で読み取ると正常に5000を取得できした。

    • ベストアンサー
    • Java
  • バイナリデータの操作

    Perlでバイナリデータの操作(たとえば画像のピクセル部分の変更)をする場合 配列に一つ一つ数値を入れて操作するのと スカラでデータをいっぺんにパック(?)して操作するのとでは どちらがいいのでしょうか? ようはC言語のchar配列の操作のようなことがしたいのですが。

    • ベストアンサー
    • Perl
  • C言語に於けるバイナリデータ

    C言語等に於けるバイナリデータは基本的に前ゼロのついた状態で電算機は記憶・処理しているのでしょうか?例えば1なら00000001のように。

  • VBAでバイナリデータが上手く読めない。

    VBAでバイナリデータが上手く読めない。 もともとC言語でバイナリデータを加工していた事をVBAでやる事になったのですが、上手く読めない。 <VBA> Open inputFileName For Binary As #mFileNo のようにオープンして、 <VBA> Dim a(800) As Byte Get #1, , a のように記述すればC言語のように取得出来ると思ったのですが、上手く取得出来ません。 なんとなく分かった事ですが、800バイトの中に改行文字があった場合、そこまでを変数aに入れるようにすると出来そうなので、Getで改行コードがあった場合はそこまでを読み込むみたいな手段はありますでしょうか。inputだとデータがまったく見れませんでしたのでGetにて対応したいと思っています。 宜しくお願い致します。

  • 補数を利用した引き算について

    こんにちは。 『2進数で 111 - 010 を計算をせよ。』 という問題があります。 つまり10進数でいう所の 7 - 2 = 5 の計算をします。 補数を利用すると引き算が足し算ででき、演算が簡単になることを 本は説明しようとしてるのですが、腑に落ちない点があります。 解説では --------------------------------- 引く数 010 の補数を求めると 101 なので  111 +101 -------- 1101  ↓  101 よって桁上がりを無視した 101 が答え --------------------------------- との事ですが疑問に思うことがいくつかあります。 I. 上記の計算では3ビットであることが前提になっています。 7 - 2 = 5 をしたいわけですから、そうすると  111 ←符号なしの表現 ( 7 ) +101 ←符号付きの表現 ( -2 ) -------- 1101  ↓  101 ←符号なしの表現 ( 5 ) となり、符号なしと符号付きの数値を混ざってしまうが、良いのでしょうか? また、この説明の仕方だと答えが 0~7 になる答えしか出せません。つまり引く数の方が大きいと計算できません。 私は補数を使うのであれば正の値・負の値、全て符号付きの値でなければいけないと思っていたので、 もし私が説明するのであれば全て符号付きにし、そして符号付きで7を表せるようにするために4ビットにして  0111 ←符号付き( 7 ) +1110 ←符号付き( -2 ) ---------- 10101  ↓  0101 ←符号付き( 5 ) とするのであれば納得できます。 答えの範囲も -8~7 と負の値も許容できます。 II. 実際には 本のように引く数だけを補数にして足し算をして答えを求めているのか、 それとも私のように正の値・負の値、ともに符号付きの表現にして足し算をしているのか、 もしくは、いずれとも違うのか、どうなのでしょうか? また、参考文献などがありましたらご紹介お願いします。 以上ですがよろしくお願いします。

  • C言語のバイナリモードでのfscanf関数の使い方について教えて下さい

    C言語のバイナリモードでのfscanf関数の使い方について教えて下さい。 2*2のint型配列バイナリデータを読み込んで、要素一つ一つを出力したいのですが、 fscanfでの書式指定の仕方がよく分かりません。 fscanf(入力元,"???",&入力先)の???の部分はどう指定すればよいのでしょうか? 下記のようなプログラムを書いたのですが、fscanfでデータを読み込めず、 data=0という出力で無限ループに入ってしまいます。 C言語初心者なので、かなり初歩的な質問かと思いますが、 よろしくお願いします。 -------------------------------------- char *fi; int data; fi = argv[1]; /* 2x2のint型配列バイナリデータを指定 */ input = fopen(fi,"rb"); while(!feof(input)){ fscanf(input,"%d",&data); printf("data=%d\n",data); } ---------------------------------------

  • Java バイナリデータの扱い

    既出でないことを確認してみたつもりです。 <やりたいこと> 1.バイナリデータに埋め込まれたデータを読み込みたい。 2.バイナリデータの並びは例えば double d1,d2; char buffer[256]; int i1, i2; などとなっていてファイルヘッダとして同じフォーマットのファイルには全て埋め込まれています。これを読み込みたいです。 <質問> C言語であれば例えば構造体を定義してやって構造体のポインタに対して ヘッダの読み込みを行ってやれば上記のdoubleなどの変数は参照できる ようになりますが、Javaで同等の処理をやろうとするとどうすれば 良いのかわかりません。 良い方法があれば教えて下さい。宜しくお願いします。

    • ベストアンサー
    • Java
  • テキストファイルをバイナリファイルに変換

    -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 130, 120, 120, 109, 100, 100, 94, 91, 90, 89, 87, -32768, 78, 71, … と続いていくテキストファイルのデータをバイナリデータにC言語で変換したいのですが、どうすれば変換出来るのでしょうか。

  • バイナリ表示されたデータを小数にかえるには?

    こんばんわ, 今,ある参考書のファイルで 「0000 1010 1010 1010 1010 1010 1010」 という28ビットのバイナリーデータが小数部分をあらわすとき,それをfloat,もしくはdouble型のxに変換せよ。 という,問題があるのですが,1つ1つ上位ビットから0.5×0+0.25×0+・・・とやっていく方法以外にビット演算子やシフト演算子,関数を使用して簡単にできる方法がありましたら教えてください。 ちなみにC言語で作成しています(データはBIGもしくはLITTLEエンディアンどちらの方法でもかまいません)。

  • ruby バイナリ入出力について

    ruby初心者です。 バイナリファイルを読み込んで、その値を2倍して再びバイナリファイルに書き込む ソースを作りたいのですが、どなたかご教示願えますでしょうか。 以下試行錯誤して作ってみたのですが、このソースだと 例えば31というバイナリデータが62で書かれず、 36、32のasciiコードで保存されてしまいます。。 ----------------------------- BinData = open("in.data") BinData.binmode File.open("out.data", "wb"){|f| while (b = BinData.read(1)) m = b.unpack('C')[0]*2     #取り込んだバイナリデータを整数化して2倍 p sprintf("%x", m) k = format("%x", m)       #16進数に変換 f.write(k) end } すみませんが宜しくお願い致します。

専門家に質問してみよう