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


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
1212
yario四捨五入の答えがおかしい11解決


yario

リンク

2013/12/12(Thu) 20:51:30|NO.58688

四捨五入するスクリプトを作ったのですが、
穴だらけみたいで答えがマイナス値になったり、0になったりします。
そのスクリプトがこちらです。

#packopt name "四捨五入" #packopt xsize 160 #packopt ysize 80 title "四捨五入" screen 0,160,80 *top taisyo=0.0 redraw 0 cls mes "小数点第" pos 64,0 objsize 34,24 combox sisya,,"1\n2\n3\n4\n5\n6\n7\n8\n9\n10" pos 97,0 mes "位の概数" pos 0,24 input taisyo,75,24 pos 75,24 mes "が対象の数" objsize 159,32 pos 0,48 button gosub "四捨る!",*kei stop *kei kotae=0 if sisya=0 :kw=1 if sisya=1 :kw=10 if sisya=2 :kw=100 if sisya=3 :kw=1000 if sisya=4 :kw=10000 if sisya=5 :kw=100000 if sisya=6 :kw=1000000 if sisya=7 :kw=10000000 if sisya=8 :kw=100000000 if sisya=9 :kw=1000000000 taisyo*kw kotae=double(int(taisyo+0.5)) kotae/kw dialog "答えは"+kotae+"でした!",0,"計算結果" return
どうかファイル完成のためにもご回答よろしくおねがいします。



この記事に返信する


GENKI

リンク

2013/12/12(Thu) 22:24:42|NO.58689

> 穴だらけみたいで答えがマイナス値になったり、0になったりします。

デバッグの一歩目はエラーの再現です。
こういう時は不具合が出る条件も合わせて教えていただけると解決も早くなります。


取り敢えず見たところ、大きい値を入れると
> kotae=double(int(taisyo+0.5))
のint(taisyo+0.5)でオーバーフローしますね。整数の上限値にひっかかっています。
ここで2147483647位上の値になると正しい計算結果が得られなくなります。


とりあえずこういうのはどうですか?

a=2147483647.0 repeat 100 mes strf("%f -> %.1f", a,a) a += 0.01 loop



yario

リンク

2013/12/12(Thu) 22:50:40|NO.58692

エラーは特にありません。
返ってくる答えがおかしいのです。
GENKIさんなぜオーバーフローするのですか?



yario

リンク

2013/12/12(Thu) 22:55:56|NO.58696

さらに聞きますが、その対処方法の意味がわかりません。strfも必要なんですか?



GENKI

リンク

2013/12/12(Thu) 23:43:55|NO.58698

> 穴だらけみたいで答えがマイナス値になったり、0になったりします。

「想定通りの動作をしない、その症状」を指して「エラー」と書いたつもりでした。
エラーメッセージが出ることを指しているわけではありません。もちろんエラーメッセージは私の所でも出ていません。
わかりにくかったようですみません。


> 返ってくる答えがおかしいのです。

入れた値と想定している結果、それに対して出てきた値のどこが正しくないと考えているのか。
質問する時はこの辺りを明確に伝えると適切な回答がもらえやすくなりますよ。
どれかが欠けると答える方は想像するしかないので、とんちんかんな回答をしがちです。


> GENKIさんなぜオーバーフローするのですか?

yarioさんのスクリプトだと、少数点第1位設定で 2147483648 入れると正しくない値(負)が出ます。

オーバーフローについては、こちらを実行してみてください。

taisyo = 2147483648.0 mes taisyo mes (taisyo+0.5) ; 2147483648.5 mes int(taisyo+0.5) ; 2147483649 に…ならない! mes double(int(taisyo+0.5)) ; 壊れたまま処理は進む。
HSPが扱える整数の範囲は -2147483648〜2147483647 です。
これを超えた値を整数のまま使おうとすると値が壊れます。(オーバーフロー)
値が壊れたまま処理を続けるので、結果も正しくない値が表示されます。


> さらに聞きますが、その対処方法の意味がわかりません。strfも必要なんですか?

手軽に四捨五入したいだけならstrfでもできるから、理屈はよく分からなくても取り敢えずstrfで回避出来るよ。ということです。
質問からは、結果が得たいのか、理屈を知りたいのか、どちらなのか読み取ることが出来なかったので取り敢えず回避方法だけ書いてみました。

taisyo = 2147483648.555 kw = 10 mes (double(strf("%.1f", taisyo*kw+0.5)) / kw)
必要ないと思うなら無理して使わなくてもいいと思います。



yario

リンク

2013/12/13(Fri) 20:06:10|NO.58710

遅れてすみません。strfでできるとは。
回答ありがとうございます



yario

リンク

2013/12/13(Fri) 20:07:46|NO.58712

テスト



さか

リンク

2013/12/13(Fri) 22:36:31|NO.58716

不具合の再現ですがGENKIさんの言うようにどういう操作をしたらどうなるのかを明記した
ほうが良いです。
以下の設定で変更せずに1回目と2回目、以降の答えが異なりますね。
小数点第「2」〜
「0.48」が〜

単純にtaisyoの所が問題ですよ。
taisyoが初期値に戻らずに*kwが繰り返されてるようです。
以下にすると直ります。
taisyo2=taisyo*kw
kotae=double(int(taisyo2+0.5))

あとtaisyo*kw、kotae/kwの書き方はtaisyo=taisyo*kw、kotae=kotae/kwと同じ動き
をするようですがhspのバグのような。。。ちょっと調べたけどわかりませんでした。
ちなみにC#ではコンパイルエラーになりました。



GENKI

リンク

2013/12/14(Sat) 00:16:43|NO.58717

初期値に戻ってなかったのか…そこは気付かなかった。(´・ω・`)


> あとtaisyo*kw、kotae/kwの書き方はtaisyo=taisyo*kw、kotae=kotae/kwと同じ動き

確かそいういう変わった仕様があったはず…と調べてみたらプログラミング・マニュアルにありました。

> ; 例
> a=10 ; 変数aに10を代入
> a+=2 ; 変数aに2を加算(a=a+2と同じ)
> 上の例では、変数aは12という値になります。 このように、「+=」を使用すると「+=」以降が変数a自身に対して加算されます。 同じように「-=」や「*=」などすべての演算子を使用することができます。 (また、「=」を省略して「変数」+「演算子」+「パラメーター」の形式でも同様の動作になります。 ただし、この書式はC言語やJavaなどとの互換性がないため推奨はされません。)

推奨される書き方ではありませんが、使用することが出来ます。
私も変わった書き方するなーとは思いましたが、書き方にこだわりがあるのかな?と思って何も言いませんでした。



check

リンク

2013/12/14(Sat) 00:19:32|NO.58718

>taisyo*kw、kotae/kwの書き方はtaisyo=taisyo*kw、kotae=kotae/kwと同じ動きをする
あまりよく覚えていないが、それはHSPの仕様だったはず。



暇人

リンク

2013/12/14(Sat) 01:31:00|NO.58720

>あとtaisyo*kw、kotae/kwの書き方はtaisyo=taisyo*kw、kotae=kotae/kwと同じ動き
結果は同じだけど
処理速度はtaisyo*kwの方が速い
2割り程度変る
taisyo=taisyo*kwはtaisyo*kw+0.0で同程度の処理時間



さか

リンク

2013/12/14(Sat) 02:24:02|NO.58721

仕様でしたか。みなさん、ありがとうございます。
コンテストのHSPTV部門で使用するとサイズが減るからいいですね。



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