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


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
0729
ヂオン#const の定数計算のバグ8解決


ヂオン

リンク

2012/7/29(Sun) 10:59:39|NO.48013

#const による定数計算と
実行ファイル化後の演算に関して多少の違いがみられるようです。


// #const の定数計算と 実行ファイル化後の計算の違いのバグについて。 #define calc 100/11 // 計算する式 #const const calc mes "#const を使用して計算した場合 : "+const // 実数と成る mes "実行ファイル内で計算した場合 : "+calc // 余りが有る場合整数と成る

これはバグなのでしょうか?



この記事に返信する


KA

リンク

2012/7/29(Sun) 17:22:50|NO.48026

おもしろそうなので試して見た。


#define C 100/11 #const A 100/11 #const B A D=100/11 mes "#const で直接計算した場合 : "+A mes "#const を使用して計算した場合 : "+B mes "#define で計算した場合 : "+C mes "直接計算した場合 : "+D

#define はマクロ内で、そういう風にされているのだと思われる。
もともと非推奨だし。



玄冬

リンク

2012/7/29(Sun) 17:31:28|NO.48027

…バグなんでしょうか?

確かに、M様の仰るようにプログラミングマニュアルには
>計算式は、整数のみで演算子および数値の記述スタイルは、スクリプトで 使用している式と同様のものが使えます。
と書かれていますが
#constのリファレンスの方には
>計算式は、整数及び実数を使用することができます。
>#const命令の直後に「double」を入れることで、 定義されている数値が強制的に実数と認識されます。
>この指定を行なわなかった場合には、小数点以下の値があるかどうかによって、整数と実数が自動的に判別されます。
と書かれています。

以前のヴァージョンのものと比較していないので推測ですが、
以前は整数しか使えなかったものが、実数も使えるようになった際、
リファレンスのみ改訂され、マニュアルの改訂が為されていないのかと思われます。

そして、今回ヂオン様の問題にしている挙動は概ねリファレンス通りの動きをしているので仕様なのではないかと思うのですが…

蛇足
M様は「HSPの演算規則」にも言及されておられます。

私見ですが、「HSPの演算規則」はあくまでもコンパイラの仕様を規定しているだけで
プリプロセッサの挙動を規定するものではないと思います。
なので、プリプロセッサで計算されコンパイラに渡る時点で定数になっている#const test 100/11が
コンパイラの計算する#define test 100/11 と計算結果が異なるのも許容されると思います。
(もちろん、リファレンスやマニュアルで挙動が説明される必要はあると思いますが)



ヂオン

リンク

2012/7/30(Mon) 12:21:10|NO.48044

とりあえずなんとか整数に直す方法を見つけたのでアップします。


#const test (100/11) - ((100\11) / 11) mes test

これってどうなるんだろう。
いつか修正されたりするのでしょうか



KA

リンク

2012/7/30(Mon) 12:40:28|NO.48045

何を疑問視しているのか分からない。

>>#const命令の直後に「double」を入れることで、 定義されている数値が強制的に
>>実数と認識されます。

>>この指定を行なわなかった場合には、小数点以下の値があるかどうかによって、整
>>数と実数が自動的に判別されます。

この自動判別が気にくわないのかな?



ヂオン

リンク

2012/7/30(Mon) 12:46:15|NO.48046

ついでに、修正された後でも、動作するように試行錯誤したスクリプトも。


// 3/2*10 = 15 で有る場合 定数が実数型に変換されている #const IS_PREPROCESSOR_CALC_DOUBLE_CONVERT ((3/2*10) == 15) #if IS_PREPROCESSOR_CALC_DOUBLE_CONVERT #define ctype prepr_divide(%1,%2) ((%1/%2) - ((%1\%2) / %2)) #else #define ctype prepr_divide(%1,%2) (%1/%2) #endif #undef IS_PREPROCESSOR_CALC_DOUBLE_CONVERT #const test prepr_divide(100,11) mes test



ヂオン

リンク

2012/7/30(Mon) 13:02:10|NO.48047

>>何を疑問視しているのか分からない。

例として掛け算を使用した際等に致命的な差が出たりします。


#define 式 3/2 #const v1 式 v2 = 式 mes v1*1000 mes v2*1000

ついでに 上の例の
v1 と
v2 の演算例では

スクリプトサイズが

v1 は 4 byte 変数の参照は1
v2 は 9 byte 変数の参照は2

となり オーバーヘッドも気になります。

(目算なので、違いは有るかも)

差は微細ですが、やはり、軽減する方法が有る以上は、軽減してコンパイルすべきではないでしょうか。



KA

リンク

2012/7/30(Mon) 16:45:07|NO.48051

>>#define 式 3/2
>>#const v1 式
>>v2 = 式
>>mes v1*1000
>>mes v2*1000

#const v1 式・・・3/2で小数を含むから実数型になり。
v2 = 式 ・・・・・整数型で計算するから四捨五入される。


#define 式 3.0/2.0 #const v1 式 v2 = 式 mes v1*1000 mes v2*1000

じゃダメなの。



ヂオン

リンク

2012/7/31(Tue) 02:02:22|NO.48055

>>KA さん

そんな方法もあるんですね。参考にさせていただきます。


とりあえず、NO.48046 の方法で、勝手に解決ということにしておきます。
幸い #const は プリプロセッサなので、いくら計算式を積んでも、使用スクリプトサイズは
4 または 8 byte(実数の場合) で済みます。重宝しています。

こんな長ったらしい演算も
 
#define global ctype MAKE32BITMASK(%1)\ ((%1>=32)<<31|(%1>=31)<<30|(%1>=30)<<29|(%1>=29)<<28|(%1>=28)<<27|(%1>=27)<<26|(%1>=26)<<25|(%1>=25)<<24|(%1>=24)<<23|(%1>=23)<<22|(%1>=22)<<21|(%1>=21)<<20|(%1>=20)<<19|(%1>=19)<<18|(%1>=18)<<17|(%1>=17)<<16|(%1>=16)<<15|(%1>=15)<<14|(%1>=14)<<13|(%1>=13)<<12|(%1>=12)<<11|(%1>=11)<<10|(%1>=10)<<9|(%1>=9)<<8|(%1>=8)<<7|(%1>=7)<<6|(%1>=6)<<5|(%1>=5)<<4|(%1>=4)<<3|(%1>=3)<<2|(%1>=2)<<1|(%1>=1)<<0) #const mask10 MAKE32BITMASK(10) mes mask10

実行ファイル化後は


mes 1023

のみで済んでとってもお得!!



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