• ベストアンサー

バイナリとBCDコード

2進法と2進化10進法の違いを簡略でいいので 教えてください! 懐かしき「2000年問題」の本を読んでいたら BCDコードの場合 コンピュータの数値認識  → 99に1が足されて   00(で一桁くりあがる) → 問題発生 バイナリ値の場合 → 1999から2000年の変化はただ1増えるに過ぎない と書いてありました。 できれば上記を踏まえて説明してくれると助かります! わかりにくい質問かもしれませんがよろしくです。

  • sinba
  • お礼率55% (5/9)

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

  • ベストアンサー
  • brogie
  • ベストアンサー率33% (131/392)
回答No.1

2進法とは(16進表現) 0,1,2,3,....8,9,A,B,C,D,F 10,11,12,13,.....18,19,1A,1B,1C,1D,1F 20,21,22,23,.... となっていきますが、整数の場合はよいですが、小数になると、2進数で表せない10進数が出てきます。このために、9のつぎは2進数でも10にするのです。 0,1,2,3,.......8,9 10,11,12,...18,19 20,21,22,...28,29 ......... COBOLなど金銭を取り扱うソフトはBCDを使ってあります。 C,C++などでもBCDを使えるようになっているようです。 10進数の0.1を10回足すと1.0になりますが、2進数ではなりません。0.1を2進数では表せないのです。普通、コンピュータの内部では2進計算ですから、 2進数では(カッコ内は10進数) 1を2で割ると・・・・・0.1(0.5) 0.1を2で割ると・・・・0.01(0.25) 0.01・・・・・・・・・・・・・0.001(0.125) 0.001・・・・・・・・・・・・0.0001(0.0625) ・・・・・・ 10進数の0.1を2進数で表すことが出来ません。 FOR i=1 TO 20   S=S+0.1   IF S=1.0 THEN PRINT"OK" NEXT i このようなプログラムではOKは表示されません。 2000年問題は、メモリの節約のために、下2桁しか使用していなかったために、99に1を足して、100になる1のメモリがありませんから、下2桁の00しか表示されなくて、1900年と認識してしまうために、計算を間違ってしまうのでした、今年は9月問題がありますが、どうなるでしょうか?2001年9月8日問題です。gooで、キーワード「9月」で検索して見て下さい。 長くなりすぎました。後の方の補足を期待して!

sinba
質問者

お礼

お礼がおくれましたが、どうもありがとうございました。 2進数は少数に弱いんですね。 そして 「9月8日」問題、さっそく調べさせていただきます!

その他の回答 (3)

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.4

簡略に説明して欲しいと言うことなので、ごく簡略に。 2進法なら2000は11111010000で表します。(11ビット) 実際には16ビットで0000011111010000で扱います。 2進法はコンピュータの計算に都合がいいのです。 実際には2進法は (1)人間に判りにくい。 (2)画面に表示したり、印刷したりするのに10進法に直さなければならない。 という欠点が有るため、10進と2進の中間の記憶形式を取ります。 これが2進化10進数(BCD:10進数の1桁づつをそれぞれ2進で表す)です。99は1001 1001のごとくです。(4ビット表示) 先の方が言われている通り、BCDの世界は乱れていて、4ビット形式、8ビット形式、符号の有り無しなど統一されていません。 2000年問題に限って言えば、BCDとは言っても下2桁を8ビットの文字コード(ASCII)2桁でファイルに保持していたといえるでしょう。 1999年は99しか持っていませんから1を足すと00(100では有りません)。従って2000年でなく1900年に戻ってしまいます。 正確でないのを承知でわかりやすく言うと2000年対策というのは先に1900を足してから1を足せば(99+1900+1)で正しい2000年が得られるということなのですね。 簡略とはいえなかったですね。(^^;;

  • msystem
  • ベストアンサー率42% (79/186)
回答No.3

われわれが普段使っているのが10進数であることと、コンピュータ内部では2進数を使っていることはご承知だと思います。そこでわれわれが使っている10進数をコンピュータが使う2進数に直すこと、またその逆を考えなければなりません。 その方法が2通りあるということです。 1つ目のBCDですが2進数は、4桁(4bit)で10進数の0から15までを表せますので、このうち0から9までを使って10進数の1桁を表す方法です。つまり、1バイト(8bit)で10進数の2桁を表すことができます。 さてここで、プログラムの書き方ですが、年を表すのにデータ容量をケチって1バイトで表すと、プログラム上で BCD 表す年 00→1900年 99→1999年 とするのが簡単でいいですね。すると、2000年を表す方法がありませんので2000年問題となるわけです。 さて、バイナリ値ですが、上記と同じ1バイト(8bit)で年を表すとすると、2進数8桁は10進数で0から255まで表すことができることになります。(2000年を正確にに表現しようとすると2進数11桁で、0から2047まで表せますので2バイト以上あればもっといいことになります) さてプログラムでは、 バイナリ 表す年 0   →1900年 99  →1999年 100  →2000年 255  →2155年 となりますので、2000年を正確に表すことができることになります。(もちろん、バイナリ値0を1900年とするという前提ですが・・・)つまり、2000年問題は起こらないということになります。 brogieさんも書いておられますが、昔はよくBCDを使っていたので(バイナリ→10進変換のプログラムの容量すら削減したかった)その当時のプログラムを使っていると問題が起こることになりますね(実際、私も昔遊びで作っていたプログラムはBCDを使って計算していました。)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

昔のコンピュータ(といっても元祖のENIACは10進計算なので除外)は“数値計算”だけを目的としていました。 10進数を2進数にすると… 0 - 0000 1 - 0001 2 - 0010 .... 7 - 0111 8 - 1000 9 - 1001 コレに符号(+と-)を加えたものを2進化10進数(Binary Coded Decimal=BCD)と呼んでいました。 その後、コンピュータで英文字を使う必要が出てきたので全体を8bitに拡張して文字と数字を表せるようになりました。 コレを拡張2進化10進コード(Extended Binary Coded Decimal Interchange Code=EBCDIC)と呼び、数字の場合BCDの値(0000~1001)は下位bitに、上位は16進のF(1111)をつけて表します。 結果、EBCDICにおける数値はF0(11110000)~F9(11111001)となります。 その後、標準コードとして制定されたASCIIコード(ASCIIを元に制定されたJISを含めて考えてください)では数字の上位を3として30(00110000)~39(00111001)となっています。 現在BCDというと1桁4bit(Pack),1桁8bitでEBCDIC(ZoneまたはUnpack),1桁8bitでASCII(ZoneまたはUnpack)の3種類があるので気をつけてください。 コレに対して数値(数字で無い事に注意)は8bitで00(00000000)~FF(11111111,10進では255)を表す事が出来ます。 10進整数99を2バイトで表現する場合を比較すると(数字はZoneでASCII) 数字=3939(00111001 00111001) 数値=0063(00000000 01100011) となります。 数字表現では1バイトで0~9しか表現できない為、2バイトで0~99が表現できます。 結果、99+1は100(3バイト必要)となり、けた上がりした最上位1桁が失われます(桁あふれ)。 対して、数値表現は2バイトで0~65536が表現可能です。 こちらは99+1=100でも2バイトで表現が可能です。 最後に、以上の説明はかなり乱暴です。 ・1バイト=8ビットを仮定している ・符号を考慮していない ・BCDの解説が大雑把すぎて正確でない etc... 正確な解説は書籍を参照して下さい。

sinba
質問者

お礼

回答どうもありがとうございました! コードについての解説が 私にとっては少々難しかったのですが、 おおまかなコードの流れがよくわかりました! 書籍等もいろいろ読みつつ私も自分自身のレベル をあげていきたいです。 どうもでした!

関連するQ&A

  • BCDコードの計算

    BCDコード(2進化10進符号)の100000110110は10進数で幾らか。 この問題がわかりませんどなたか教えてください。お願いします。

  • 10進数をBCDに変換する方法

    10進数から2進化10進数(BCD)に変換するところで疑問があります。 たとえば、10進数の3846をBCDに変換する場合答えはどのようになりますか? 私なりに考えたところまでを示しますが、答えがわかりません。 どこに考え方の間違いがあるのでしょうか? まず、3846を2進数に変換しました。 3846 → 0000111100000110 (2進数)となります。 ここからBCDに変換する場合、4ビットずつを1つと考えて数字を表現するので、上記の2進数の頭から4つずつ分けて考えると 1つ目 0000 2つ目 1111 3つ目 0000 4つ目 0110 の4つにわけました。 続いて、それぞれを10進化しました。 1つ目 0000 → 0 2つ目 1111 → 15 3つ目 0000 → 0 4つ目 0110 → 6 ここで疑問が出てきます。 2つ目のところで、1111を10進化すると15となってしまい桁上りが生じます。 この場合どのように処理するのが良いのでしょうか? どなたかご教授ください。

  • 10進数をBCDに変換する方法

    10進数から2進化10進数(BCD)に変換するところで疑問があります。 たとえば、10進数の3846をBCDに変換する場合答えはどのようになりますか? 私なりに考えたところまでを示しますが、答えがわかりません。 どこに考え方の間違いがあるのでしょうか? まず、3846を2進数に変換しました。 3846 → 0000111100000110 (2進数)となります。 ここからBCDに変換する場合、4ビットずつを1つと考えて数字を表現するので、上記の2進数の頭から4つずつ分けて考えると 1つ目 0000 2つ目 1111 3つ目 0000 4つ目 0110 の4つにわけました。 続いて、それぞれを10進化しました。 1つ目 0000 → 0 2つ目 1111 → 15 3つ目 0000 → 0 4つ目 0110 → 6 ここで疑問が出てきます。 2つ目のところで、1111を10進化すると15となってしまい桁上りが生じます。 この場合どのように処理するのが良いのでしょうか? どなたかご教授ください。

  • シーケンサー入力で装置でよくBCDコード1248と言いますが。

    シーケンサー入力で装置でよくBCDコード1248と言いますが。 シーケンサーやカウンターの入力でよく1248(いち に よん ぱ)と言いますが、これはBCDコードを言っていると思います。  BCDコードでは2進法の0を0000で表記する為、最大16通りの組み合わせができると考えればよいのでしょうか? また何故制御機器で入力を言う場合1248と呼ぶのでしょうか?  よろしく解説お願いします。

  • 2進数からBCDコードへの変換

    今,2進カウンタを作り,これから7セグメントLEDへ出力する回路を作りたいのですが,1桁の場合は,デコーダICでそのまま変換可能なのですが,10進数に直したときに2桁以上になるものは,デコーダの前で各桁ごとのBCDコードに分けてあげないといけなくなります。ここが分からないのです。 回路の構成としては,カウンタ部分をアナログで構成し,そこで8個のスイッチをつけて,それぞれ2進数の各桁の入力としています。これと,3個のデコーダICと7セグメントLEDで2^8=255までを表示させたいのですが,どのような回路構成だとシンプルに作れるのでしょうか。また,そのようなICは存在するのでしょうか。

  • UNIXのバイナリファイル→WINDOWSのバイナリファイル(互換性ありますか?)

    UNIXで計算させた数値をバイナリ形式のファイルで保存しています。このファイルをWINDOWS上のメモ帳で開くとUNIX上のものと異なった数値が表示されました。数値の個数は合っているのですが,何か問題はあるでしょうか。互換性がない場合の対処法もご教授願えれば助かります。説明補足が必要な場合はどんどん要求してください。よろしくお願いします。

  • BCD出力で表示されたものをBINに変換すると

    PLC制御を学び始めた初心者です。 BCD出力とBIN出力について勉強している中で、たとえばヒーターの温度設定を行うことを想定して、BCD出力をするタッチパネルを用いて行った温度設定を場合について疑問があります。 たとえば、表示パネル上で63℃と設定したとします。 BCDなので、各桁それぞれを2進数で表して 6→0110 3→0011 つまり 63 = 0110 0011 ということになりますよね。 さらに、データをCPUやPLCに取り込むときにBINデータに変換する必要があると思うのですが、これをBINデータに変換する場合、上記のBCDデータを通常の2進数と見て、一度10進数に戻し、それを再度2進数に戻す作業になると思います。 具体的には、 01100011 =1+2^1+2^5+2^6=102 したがって、10進数の102という数値になりますよね? これを再度2進数化したものがBIN変換した数値ということになると思いますので、 102 = 01100110 (2進数) という風になるかと思います。 つまりPLCの内部ではこの2進数をデータとして取り扱うことになるかと思いますが、 さて、ここでよくわからないのですが、 タッチパネル上では63℃として入力していたのに、内部に入ったら102(℃?単位はわかりませんが・・・)として扱われています。 ここがよくわかりません。63℃のはずが102に変換されてしまっています。 だったら最初から変換などせずにそのままでいいのではないかとも思うのですが?? どなたがご教授いただけませんでしょうか。 なぜBINとBCDが扱われるのかについても教えていただけると幸いです。

  • 言語コードの2文字または、3文字または、3桁の数値コードの記述について

    普通言語コードを記述するとき、アメリカの英語だとしたら「en-us」となりますが、アルファベット3文字や3桁の数値のコードも使用できるのでしょうか? 例えば、アメリカの場合2文字は「us」、3文字は「usa」、3桁数値は「840」なので、言語コードをアメリカの英語とする場合、「en-usa」や「en-840」と記述してよいのでしょうか? 回答よろしくお願いします。

    • ベストアンサー
    • HTML
  • バイナリーBCD変換アプリAN526ついて

    PICの入門者です。温度計を作るべくプログラムを勉強しているのですが、温度表示をする際、バイナリ-からBCDに変換するには、書物によるとMicro chip社のアプリケーションンノートAN526をコピー使用すると良いことが記述されており、実際コピーしてい使用すると問題ないのですが、プログラムのアルゴリズムは何とか理解できましたが、プログラムの詳細が解りません。どなたかアドバイス頂ければ有り難いです。 (理解できない部分) 1、定数 L_byte、H_byte、R2、R1、R0をrlfを実行して decfsz count,Fでcountが16以内であれば adj DECにジャンプする訳ですが、そこでmovlw R2(R1,R0)→ movwf FSR となっていますがこの間接アドレッシングの方法が?   2、さらにSUBルーチン adjBCD でmovlw 3 →  addwf  0,w  とありますがここでaddwf 0,wの0はINDFを指している理解しましたが正しいでしょうか?  *R2(R1,R0)の値が指定するメモリー番地の値となると変数R2(R1,R0)の値は8bitの範囲で変化するのでSFRの番地に被ってしまわないか?ということです。 私の考え方間違っていると思いますがご指摘ください。 アプリケーションAN526抜粋 B2_BCD        bcf  STATUS,0        movlw .16       movwf count        clrf R0       clrf R1       clrf R2 RHloop16        rlf L_byte,F       rlf H_byte,F       rlf R2,F       rlf R1,F       rlf R0,F        decfsz count,F       goto adjBCD       retlw 0 adjDEC       movlw R2  ←変数R2の値は8bitの範囲で変わると思われるがSFRに被ることはない        movwf FSR  ←       call adjBCD       movlw R1       movwf FSR       call adjBCD       movlw R0       movwf FSR       call adjBCD       goto RHloop16 adjBCD       movlw 3       addwf 0,w  ←  0はINDFの意味?つまり定数R2,1,0の指定する番地の値に+3する?   以下省略

  • バイナリファイルとソースコードのバージョン一致確認

    わかりにくいタイトルですみません。 とあるアプリケーション(Win3.11 EXE)が存在し、そのソースコードも存在します。 しかし、15年以上の時間経過で当時の担当者達は全員退職し、また会社の吸収合併や組織変更などの影響で、そのソースコードが現在動いているアプリケーションと同じバージョンかどうか、つまり今あるソースコードで現在のアプリケーションのバイナリファイルを作成できるのかどうかがわからなくなりました。 そのソースコードが現在動いているアプリケーションと同じバージョンかどうかを確認するには、どのような方法が考えられるでしょうか? 例えば、ソースコードをコンパイルしてファイルサイズが同じならかなりの確立でバージョンが一致していると想定していいのではないかと考えていますが、Windows(3.11)やコンパイラ(VC++1.52)が同じなら、同じソースを同じオプションでコンパイルしたら同じバイナリファイルが生成されるでしょうか? また、上記の方法がNGな場合、他にどのような確認方法が考えられますでしょうか? 今までこのような問題に遭遇したことがないため、いろいろなアイディアがほしいです。お知恵をお貸しください。

専門家に質問してみよう