HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0610
n10tondebug viewの表示が異なるのは?4解決


n10ton

リンク

2016/6/10(Fri) 11:37:54|NO.75815

# knowbug(version: 1.22)を大変便利に利用させて頂いて下ります。
アプリの開発に感謝し、お礼申し上げます。
さて、下記のスクリプトで疑問が出てきました。
演算結果は期待通りですが、デバッグ中に下記の点に気づき投稿するものです。
この差は何なのか判らず、気になってしかたありません。
ご多忙とは思いますが、余裕のあるときに、気に掛けて頂ければ幸いです。

double関数で
下記の変数(型: double)で一部表示が異なって見えます。
double関数に1.4や2.4をセットすると、内容が他の数字の場合と少し異なるのは
何故でしょうか。
assert //+++++++++
; debug windowの表示内容
wreg01 = 1.0 ;wreg01 = 1.0000000000000000
wreg01 = 1.1 ;wreg01 = 1.1000000000000001
wreg01 = 1.2 ;wreg01 = 1.2000000000000000
wreg01 = 1.3 ;wreg01 = 1.3000000000000000
wreg01 = 1.4 ;wreg01 = 1.3999999999999999
mes wreg01 ;1.400000 メッセージ表示
wreg01 = 1.5 ;wreg01 = 1.5000000000000000
wreg01 = 1.6 ;wreg01 = 1.6000000000000001
wreg01 = 1.7 ;wreg01 = 1.7000000000000000
wreg01 = 1.8 ;wreg01 = 1.8000000000000000
wreg01 = 1.9 ;wreg01 = 1.8999999999999999
wreg01 = 0.4 ;wreg01 = 0.4000000000000000
wreg01 = 2.4 ;wreg01 = 2.3999999999999999
wreg01 = 2.6 ;wreg01 = 2.6000000000000001
wreg01 = 2.40 ;wreg01 = 2.3999999999999999

wreg01 = 1.4 ;wreg01 = 1.3999999999999999
wreg02 = 2.4 ;wreg01 = 2.3999999999999999
wreg03 = wreg01 + wreg02 ;wreg03 = 3.7999999999999998
mes wreg03 ;3.800000 メッセージ表示
stop



この記事に返信する


KA

リンク

2016/6/11(Sat) 07:22:02|NO.75832

下記と同じ理由です。

http://hsp.tv/play/pforum.php?mode=all&num=75755



n10ton

リンク

2016/6/12(Sun) 09:14:29|NO.75849

KAさん 有難う御座います。
ご明示頂いたスレを拝見しましたが、
残念ながら、私のレベルではついていけるものではありませんでした。
今回の件は『こうなるものだ』と言う現実を受け入れて、
解決とさせていただきます。有難うございました。



3k

リンク

2016/6/12(Sun) 11:01:45|NO.75851

> n10tonさん
多分表示の話だと思うんですが、表示的にはデバッグウィンドウの方が正しい内容を出していますね。
「1.4 や 2.4 を mes でだした時は想定通りの値がでているのに…」と思われてるかもしれませんが、表示する際に値が丸められてるだけです。


wreg01 = 1.4 mes wreg01 repeat 16 mes strf("%."+(cnt+4)+"f", wreg01) loop

何故こういったややこしい問題があるのかの本質はKAさんが答えていらっしゃる通り「CPU上で該当の値を表現しきれないから」に尽きますが、ちょっとだけかいつまんで話します。

CPU上では「0 か 1 か」という値しか扱えません。(これはもう回路上の都合なので、流石にここでは割愛します)
それだけでは数値の計算ができないので、CPUが扱える「0 か 1 か」の値のまとまりを、2進数のそれぞれの位に見立てることにしました。


… <2^3=8の位> <2^2=4の位> <2^1=2の位> <2^0=1の位> 10進法では 0 0 0 1 = 1 0 0 1 0 = 2 0 0 1 1 = 3   …

これで整数の計算はできるようになりましたが、まだ小数点(というか実数)は計算できません、困った。
でも答えは簡単で、10進数のように2進数でも小数点以下の位についても定義してあげればよいだけでした。


… <2^0=1の位> <2^-1=0.5の位> <2^-2=0.25の位> <2^-3=0.125の位> … 10進法では 1 0 0 0 = 1 0 1 0 0 = 0.5 1 1 0 0 = 1.5   …

これで実数もうまく表現できるようになりましたが、どのような実数も完全に表現するには無限のビット数が必要になります。
(この辺は、πを表現するのに10進数でも無限桁必要であることと同じ話で、そもそも実数は無限桁必要です)

一方でPCが覚えておける「0 か 1 かの値」(ビット)は無限ではなく、しかも扱える実数は多い方が一般的にはいいです。
ということで、実数を表現するのにはそこそこのビット数だけを使うようになりました。
どれくらいのビット数を使うのかはもう「こういう取り決めがある」とかそういうレベルの話で、一般的なCPUならIEEE754というのがそれに当たります。
(具体的なビット数について触れるとdoubleは64ビットで、厳密に言うなら上述の位に割り当てられてるのは52ビットです
 …本当はもっと色んな話が絡んでくるのですが、それを書くには前提となる知識をまだまだ説明しないといけないので割愛します)

これらの話を合わせると、実数でも完全に表現できるものとできないものがあること、分かりますでしょうか?
簡単にいうと「2^N乗を組み合わせた実数」は完全に表現できますが、そうでないものはできません。
また、「2^N乗を組み合わせた実数」であっても、ある程度ビット数が必要そうなものはできません。
1,5や1.25が大丈夫で、1.4がダメなのはそういう話でした。
(「でも1.2とか1.3はちゃんと値でてるやーん」みたいな話はまたややこしくなるので割愛します)

…なんか、長くなっちゃいましたスミマセン。



n10ton

リンク

2016/6/13(Mon) 14:23:24|NO.75871

3kさん
追加回答有難うございます。
正に、3kさんの仰る通りで、デバッグ中で『変な値が出るので、何故?』でした。
低レベルな質問に、3kさん、KAさん、丁寧に回答頂き感謝しております。
私に頭では、指数部が同じで、仮数部で桁上げや桁下げが起こらない演算なら、
桁数の小さい整数の計算と同じと思っておりました。
奥深い所まで全く考えが及びませんでした。

有難う御座いました。



ONION software Copyright 1997-2023(c) All rights reserved.