ビット演算

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
きい

ビット演算

#1

投稿記事 by きい » 16年前

課題で出たのdすが、わからないのでもしよろしければ教えてください。
0~255の整数値をマイナス符号に置き換え、ビット列として表現するプログラムです。ビット列は12ビットです。
手順:10進数から二進数に変換。
その変換したものを反転させる。
さらに、「1」を加え(2の補数とり)表示。
10進数から、2進数の変換までは教科書をみながら出来たのですが、そのあとが;;

御津凪

Re:ビット演算

#2

投稿記事 by 御津凪 » 16年前

先に対象の整数値をビット反転し、2の補数とりのための1を足し、
その値から10進数から2進数の変換処理を行なえば出来ると思います。

提示されている手順どおりに処理を行なわなければならないのなら、この回答は無意味ですが。

朽木

Re:ビット演算

#3

投稿記事 by 朽木 » 16年前

ビット列として表現する、ということは、10は 0000 0000 1010 、15 は 0000 0000 1111 、ということですか?(反転無視)

プログラミングの課題で 10 進数から 2進数 への変換という表現は少々罠な感じがしますが、

とりあえず、ビット演算子というものをGoogleなどで調べてみると良いでしょう。

http://www.google.co.jp/search?hl=ja&q=ビット演算子

表現については for文 と printf() で十分なはずです。 ってか、3ポイントってどういうこと… (・ω・`)

SCI

Re:ビット演算

#4

投稿記事 by SCI » 16年前

質問者さん
課題ということは「使ってもいいこと」「使っちゃダメなこと(習ってないこと?)」とか、制限がありませんか?
タイトル通り「ビット演算」をズバリ使ってもいいなら、御津凪さんの方法で(手順は変わりますが)一発ですね。

たかぎ

Re:ビット演算

#5

投稿記事 by たかぎ » 16年前

何が分からないのか分かりませんが、C++なら、
#include <iostream>
#include <cstdlib>
#include <bitset>
#include <string>

std::string compl2(const std::string& decimal)
{
  std::bitset<12> bs(std::strtoul(decimal.c_str(), 0, 10));
  bs = ~bs;
  bs = bs.to_ulong() + 1;
  return bs.to_string<char, std::char_traits<char> >();
}

int main()
{
  std::cout << compl2("123") << std::endl;
}
といったところです。

non

Re:ビット演算

#6

投稿記事 by non » 16年前

>手順:10進数から二進数に変換。

これは、何をすればいいのかがわかりません。

>10進数から、2進数の変換までは教科書をみながら出来たのですが

ここまでのプログラムを載せてもらえますか?

朽木

Re:ビット演算

#7

投稿記事 by 朽木 » 16年前

とりあえず、言語の指定が無い以上、ここで出されるべき言語はCですから、C++で出す意味は無いと思いますよ。

Cを習っている人から見れば、「え?こんなに難しいことをしなければいけないの?」という混乱をしてしまい、

無益な回答で、せっかく学習意欲のある質問者がかわいそうです。

アメリカで買った本とイギリスで買った本を持ち帰って二つとも同じにみて勉強してしまい、いざとなった時に

通じなかったり、まったく意味が異なっていて泣き寝入りしてしまうのと同じような結果に繋がります。

「C++も勉強する事になるかもしれないし?いいじゃん」ではなく、今勉強している事について、

手を差し出すべきではないでしょうか。



で、連投で申し訳ないんですが、

10進数から2進数に変換ですが、もしかして12( + 番兵)バイトの文字列に変えるということでしょうか。

もっと詳しい情報が欲しいです。プログラムは実行できない状態でも良いので載せて頂けますか。

SCI

Re:ビット演算

#8

投稿記事 by SCI » 16年前

朽木さん
>無益な回答で、せっかく学習意欲のある質問者がかわいそうです。

そのような意欲ある学生さんは、まず自分で調べ、分からなければ「学校で」質問等するでしょう。
それを踏まえてここで回答を得ようと思うなら、当然必要な情報はすべて掲載するでしょう。
ここはリファレンスではありません。文字の向こうには「回答者」が存在する、公共の場です。

たかぎ

Re:ビット演算

#9

投稿記事 by たかぎ » 16年前

> ここで出されるべき言語はCですから、

そんなことは決まっていません。
この掲示板では、DXライブラリの話題も多く、その場合は暗黙的にC++ですからね。
そもそも、環境も不明なら、自分で作ったソースも貼っていませんから、どうしようもありません。

> C++で出す意味は無いと思いますよ。

意味がないかどうかは当の本人にしか分かりませんね。

> 無益な回答で、せっかく学習意欲のある質問者がかわいそうです。

本当に学習意欲があれば、得られた情報を無駄にするようなことはありません。
それに、利用規約ぐらいは把握し、それを実行するはずですね。

たかぎ

Re:ビット演算

#10

投稿記事 by たかぎ » 16年前

一応Cでも書いてみました。
#include <stdio.h>
#include <stdlib.h>

#define DIGIT 12

void compl2(_Bool binary[DIGIT], const char *decimal)
{
  unsigned long value = strtol(decimal, NULL, 10);
  for (size_t i = 0; i < DIGIT; i++)
    binary = value & (1ul << i);

  for (size_t i = 0; i < DIGIT; i++)
    binary = !binary;

  _Bool carry = 1;
  for (size_t i = 0; i < DIGIT; i++)
  {
    unsigned t = binary + carry;
    binary = t & 1;
    carry = t > 1;
  }
}

int main(void)
{
  _Bool binary[DIGIT];

  compl2(binary, "123");
  for (size_t i = 0; i < DIGIT; i++)
    printf("%c", binary[DIGIT - 1 - i] ? '1' : '0');
}


> 「え?こんなに難しいことをしなければいけないの?」という混乱をしてしまい、

どう考えてもC++の方が簡単です。

やそ

Re:ビット演算

#11

投稿記事 by やそ » 16年前

まずは、掲示板の上にある、
必ずお読み下さい → 規約と注意事項

から規約を読んで、
”質問の仕方”
を手に入れましょう。

読めばお分かりになると思いますが、
必要な情報が足りません。

課題はC?C++?

課題として出された設問文?に制限項目などありますか?
使用できる命令とか使用してはいけないものとか(ビット演算子は使えるの??)

また、ご自分が作成されたプログラム(10進数から2進数への変換)
はここに載せられますか?

>10進数から、2進数の変換までは教科書をみながら出来たのですが、そのあとが;;
ということですが、

>その変換したものを反転させる。
>さらに、「1」を加え(2の補数とり)表示。
の部分だけアドバイスできれば良いのでしょうか?


 

きい

Re:ビット演算

#12

投稿記事 by きい » 16年前

バイトなどでかなり見るのが遅くなりましたが、回答をしてくださった方々ありがとうございます。
言語はC++です;
条件はあの手順だと思います。そう書いてるので。
0~255の数字は入力する数字です。
10から2進数の変換のプログラムは、ほぼ教科書どおりです。

12バイトのことだと思います。


返信が遅くなり申し訳ございません。

SCI

Re:ビット演算

#13

投稿記事 by SCI » 16年前

とにかく、自分で作ったソースを載せましょう。
また「教科書どおり」で話が通じる人は、おそらくここにはいませんよ。

conio

Re:ビット演算

#14

投稿記事 by conio » 16年前

①10進数から2進数に変換。
②その変換したものを反転させる。
③さらに、「1」を加え(2の補数とり)表示。

まず、①が良く分からないのです。
”10進数から2進数の変換するプログラム”を書いたという事ですか?

例えば、
int a = 10;
こうすれば、既に内部では2進数になっていますよ。
特にプログラムにする部分は無いと思います。

次に、②は補数演算子~ を使えばいいと思います。
③は、単純に1を足して、
表示する時は、
-------------------------------------------------------------
11ビット右へシフトしたものと、1の論理績& をとったものを表示
10ビット右へシフトしたものと、1の論理績& をとったものを表示
9ビット右へシフトしたものと、1の論理績& をとったものを表示
8ビット右へシフトしたものと、1の論理績& をとったものを表示
<以下略>
-------------------------------------------------------------
これをfor文か何かで実装すればいいと思います。

T.K.

Re:ビット演算

#15

投稿記事 by T.K. » 16年前

もうすでにたかぎさんが回答されているので恐縮ですが、
もう少し簡単そうに(ごつさをなくして)書きました。
たかぎさんの回答がベースです。

#include <iostream>
#include <bitset>

std::string
compl2(int decimal)
{
  std::bitset<12> bs(~decimal + 1);
  return bs.to_string();
}

int
main()
{
  std::cout << compl2(123) << std::endl;

  return 0;
}
VC++では通りますがBCCでは通りません。

書いておいてなんですが、conioさんの仰っている様な感じでシフト演算するのが
先生の期待している回答かもしれませんね。

たかぎ

Re:ビット演算

#16

投稿記事 by たかぎ » 16年前

> VC++では通りますがBCCでは通りません。

それは、

> return bs.to_string();

この部分に移植性がないからです。
移植性を持たせるには、

return bs.to_string<char, std::char_traits<char> >();

としなければなりません。

ところで、整数値のまま2の補数を求めてよいのであれば、
#include <iostream>
#include <bitset>

int main()
{
  unsigned value;
  std::cin >> value;
  std::cout << std::bitset<12>(~value + 1) << std::endl;
  return 0;
}
↑で十分ですね。

> シフト演算するのが
> 先生の期待している回答かもしれませんね。

それを質問内容から読み取るのは困難ですが、一般論で言えば、bitsetで済むものをわざわざスクラッチで実装する意味はありません。
自立処理系とかなら話は別ですが...。

T.K.

Re:ビット演算

#17

投稿記事 by T.K. » 16年前

>> たかぎさん
全て仰る通りだと思います。

移植性をなくしたのは故意です。テンプレート引数があるだけで読んで貰えなくなる
と思ったので削除して、注意としてコンパイラ依存であることを記しました。

学校の問題は現実の問題とはかけ離れているので混乱しますね。
自分がシフト演算がなんたら~と書いたのは先生が10進数と2進数の変換を
手動(?)で体験させようとしているのではないかと推察したからです(体験に基づく)。

まあ結局のところ追加の情報が無いと意味のある議論はできませんね。

>> きいさん
学校のC(++)の授業で役立ちそうな参考書を紹介します。

  ハッカーのたのしみ(エスアイビー・アクセス)
  BINARY HACKS(オライリー)

きっと役に立つと思います。(2冊目は微妙かな?)

たかぎ

Re:ビット演算

#18

投稿記事 by たかぎ » 16年前

> 移植性をなくしたのは故意です。テンプレート引数があるだけで読んで貰えなくなる
> と思ったので削除して、注意としてコンパイラ依存であることを記しました。

std::bitset::to_stringは設計ミスですよね。
C++0Xでは、明示的にテンプレート実引数を指定しなくても大丈夫になるようです。

> 自分がシフト演算がなんたら~と書いたのは先生が10進数と2進数の変換を
> 手動(?)で体験させようとしているのではないかと推察したからです(体験に基づく)。

まあ、そんな気はしますが...
それであれば、課題に明文化する必要がありますね。
あるいは、先生と学生・生徒との間に暗黙の了解があるのなら、きいさんが質問時にそれを補足する必要があります。

閉鎖

“C言語何でも質問掲示板” へ戻る