- ベストアンサー
このバグの解消方法は?
実行してみれば分かると思いますが,以下のコードは自分が製作した進数変換プログラムです。しかし,文字数が多いとバグが出てしまう事が発見されました。この問題を解決するには,どこをどのように修正すべきなのでしょうか。 <br><script type=text/javascript><!-- function convdh(){dd=eval(document.toHex.DecData.value);document.toHex.HexResult.value=dd.toString(36);} function convhd(){hh=eval(0x+document.toDec.HexData.value);document.toDec.DecResult.value=hh.toString(10);} function compute() {s = document.f3.type.selectedIndex; if(s==0) z = parseInt(document.f3.n1.value,36); document.f3.result.value = z;} //--></script><form name=toHex><textarea name=DecData>ここに入力された10進数は,</textarea><textarea name=HexResult>36進数化されてここに表示されます。</textarea><input type=button onclick=convdh() value=演算></form><br><br><form name=f3><textarea name=n1>ここに入力された36進数は,</textarea><textarea name=result>10進数化されてここに表示されます。</textarea><input type=button onclick=compute(); name=check value=演算><br><br><select name=type><option selected>♥</option></select></form><br> ジャバスクリプトは初心者です。お願いします!
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
私はJavaの経験はありませんので一般的なプログラミングの観点から述べます。一般論ですが基本的なことですのですべてJAVAにも該当すると思います。 まず、全ての型には上限/下限があります。 人間は、(原理的には)100桁でも1000桁でも計算可能ですが、 プログラミングの場合、上限・下限があることに注意しないといけません。 また、コンピュータは(基本的に)2進数で計算します。 人間は10進数ですね。 整数の場合は2進と10進で完全に互換性があります。 しかし、小数はそうではありません。 10進の小数で1/3が表せない(無限小数になってしまう) ように 2進でも10進の0.1を表現できません。 先ほど述べたように型には限界があるので プログラミングの場合は 近似値で扱うしかありません。 以上のことを前提にしてください 型には限界があると申しましたが これらはいわゆる"数値型"に関するお話です。 文字列の場合 (厳密にはメモリの制限を受けますが) 長さに制限がありません。 (一部の言語では最大文字数に制限がある場合もあります) この違いも重要です。 さて、コンピュータが計算をする過程について考察します。 簡単な例として テキストボックス2つに入れられた数値2つを加算し 計算結果を別のテキストボックスに表示するものとします。 この場合、入力データは2つとも文字列で読み取っています。 計算のために一旦数値型(バイナリ)に直します。 そうしてバイナリで計算して和を求め バイナリ==>文字列変換をして表示します なぜ、文字列==> バイナリ、バイナリ ==>文字列と変換をするのでしょう? 無駄ではないでしょうか? それは、バイナリの計算は"圧倒的に速い"からです。 その代償として 先ほどからしつこく述べています ”上限/下限"の制限が付きまといます。 文字列からバイナリの上限を超えての変換はできません。 無理やり使っても正しい結果は得られません。 いま、私は バイナリの計算は"圧倒的に速い と述べました。 バイナリ以外計算できない と述べていないことに注意してください。 そうです。 文字列のままでも計算は可能なのです。 しかし ”圧倒的に遅い" です。 そのため、多くの言語では文字列のままでの計算をサポートしていません。 先ほど述べたように 一旦バイナリに変換してから行うようになっています。 通常の言語に備わっている10進<==>16進変換なども 例え入力・出力とも文字列であっても バイナリ経由で変換されます。 したがって、上下限が付きまといます。 では (整数限定で) 10進 <==> N進 変換を(桁数制限なく)行うにはどうすればよいか? 自分で計算プログラムを作成するしかありません 文字列同士で和を求めるプログラムを作成するのです。 まるで人間が筆算で計算するように 1桁毎に計算し、繰り上がりを上位に加算し... こういうプログラムを作れば (メモリに入る限り) 1万桁でも10万桁でも計算可能です。 ただし、計算スピードは相当遅いので 5桁や6桁など整数型に収まる範囲では 使う意味はまったくありません。 あくまで、巨大な数の変換に関し ”仕方なく_" 使うべきものです。
その他の回答 (3)
- mibusys
- ベストアンサー率60% (18/30)
指数表現で表示されるのは正常な動作です。それは仕様です。 「不完全な表現」という言い方は間違いです。 で、あなたは「指数表現にしたくない」ということがいいたいのですよね。 可能かどうかで言えば可能です。そんなに難しくはありませんが、 「ジャバスクリプトは初心者」の方には難しいかもしれません。 簡単に書きますと、指数表現にならない程度に小さい数に割って、 そのあまりを変換します。それを下位の文字列表現とします。 で、割った商をさらに割りまたそのあまりを文字に変換してさっきの文字列の上位に結合。 それを割る数より小さくなるまで繰り返すという感じのループを作ればOKです。 使うもののヒントを書いておきます。 / % > while
お礼
*ありがとうございました*
補足
不完全というのは,あくまで純粋に進数変換を行うプログラムとしてです。そして,その割るといった処理はどのようにすれば良いのでしょうか。お願いします。
- mibusys
- ベストアンサー率60% (18/30)
Number.MAX_VALUEを超えると「Infinity」になります。 それ以下(Number.MAX_VALUE)だと「1.a1e14t0s2c3(e+198)」等の指数表現になります。 非常に小さい値(500000000000000000)だと「3sr77gzykagw」等の表現になります。 すべてNumber型のtoStringの仕様どおりの正常な動作です。 私の環境ではバグらしい動きは見られませんでした。 あなたがどのような値を入れてどのような結果がでたのかがわかりません。 また、どのような現象をもってバグだと判断したのかもわかりません。 が、バグは無い様に思えます。 正常な動きを知らずにバグだと思い込んでいるだけということはありませんか?
お礼
*ありがとうございました*
補足
投稿ありがとうございます。バグとは,n進数からm進数へ変換するプログラムを記述したつもりが,貴方が例にあげているようにある文字数を超えると「1.a1e14t0s2c3(e+198).」のような不完全な表現になってしまう現象の事です。なんとか10進数と36進数の完全な相互変換を成功させるのは不可能なのでしょうか。何か方法等あればお願いします。
- fujillin
- ベストアンサー率61% (1594/2576)
改行なしの質問文なので、ソースは一切みてませんが… javascriptの有効桁数を超えてるってことはないの? 有効桁数は整数だと10進で15、6桁くらいだったような曖昧な記憶。 (整数演算なのかどうかも見てないけど…)
お礼
*ありがとうございました*
補足
早速の投稿ありがとうございます。「改行なしの質問文なので...」とはいったいどういう意味でしょうか。質問文には改行もあります。普通にコードをテキストファイルとして拡張子を.htmlで保存すればそのままプログラムとして起動できる状態ですよ。有効桁数を超えているのではないかとありますが,10進数と36進数の完全な相互変換を成功させるのは不可能なのでしょうか。何か方法等あればお願いします。
お礼
ありがとうございました! <br><script type=text/javascript><!-- function convdh(){dd=eval(document.toHex.DecData.value);document.toHex.HexResult.value=dd.toString(36);} function convhd(){hh=eval(0x+document.toDec.HexData.value);document.toDec.DecResult.value=hh.toString(10);} function compute() {s = document.f3.type.selectedIndex; if(s==0) z = parseInt(document.f3.n1.value,36); document.f3.result.value = z;} //--></script><form name=toHex><textarea name=DecData>ここに入力された10進数は,</textarea><textarea name=HexResult>36進数化されてここに表示されます。</textarea><input type=button onclick=convdh() value=演算></form><br><br><form name=f3><textarea name=n1>ここに入力された36進数は,</textarea><textarea name=result>10進数化されてここに表示されます。</textarea><input type=button onclick=compute(); name=check value=演算><br><br><select name=type><option selected>♥</option></select></form><br> ~
補足
詳しい説明をありがとうございます。※JAVAではなくJavaScriptです。少数計算をするつもりはないので,つまりその上限の問題ですね。直接文字列を扱うプログラムをつくるという方法は,今まで知らなかった知識でしたし確かに良い考えだとは思うのですが,まずどう手をつけたら良いのか見当がつきません。