前回の年越しの瞬間、何してた?

2進法と2進化10進法の違いを簡略でいいので
教えてください!

懐かしき「2000年問題」の本を読んでいたら

BCDコードの場合

コンピュータの数値認識 
→ 99に1が足されて
  00(で一桁くりあがる)
→ 問題発生

バイナリ値の場合
→ 1999から2000年の変化はただ1増えるに過ぎない

と書いてありました。
できれば上記を踏まえて説明してくれると助かります!
わかりにくい質問かもしれませんがよろしくです。

A 回答 (4件)

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月」で検索して見て下さい。

長くなりすぎました。後の方の補足を期待して!
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/08/03 12:44

簡略に説明して欲しいと言うことなので、ごく簡略に。



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年が得られるということなのですね。

簡略とはいえなかったですね。(^^;;
    • good
    • 0

われわれが普段使っているのが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を使って計算していました。)
    • good
    • 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...
正確な解説は書籍を参照して下さい。
    • good
    • 0
この回答へのお礼

回答どうもありがとうございました!
コードについての解説が
私にとっては少々難しかったのですが、
おおまかなコードの流れがよくわかりました!

書籍等もいろいろ読みつつ私も自分自身のレベル
をあげていきたいです。
どうもでした!

お礼日時:2001/08/03 12:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報