整数の演算後、オーバーフローを判定する方法は、あるのですか?
勿論、ライブラリーレベルでもかまいません。
> 整数の演算後、オーバーフローを判定する方法は、あるのですか?
> 勿論、ライブラリーレベルでもかまいません。
演算 *後* では遅いと思いますが、、、
符号付き型の場合、演算を行なう前に判定しておかないと、オーバーフ
ローが起きた場合は未定義動作になります。
int 型の変数 a と b の加算を例にすると、
b > 0 ? a > INT_MAX - b : a < INT_MIN - b
が 1 になる時、a + b はオーバーフローします。他の演算も同様な考
え方で判定します。
#“変数”としたのは、a、b を複数回評価するため
K&R C などのように INT_MAX などが定義されていない場合は、内部表
現を利用した判定方法を使う手もあります。
例えば、
2 の補数表現
オーバーフローは無視する
の処理系で、int 型の変数 a と b の加算の場合は、
(a ^ b) >= 0 && (a ^ a + b) < 0
で判定できます。
PS
“オーバーフロー”の判定なので、符号無し数のことは取り上げません
でした。
--
片山@PFU
KATAYAMA Yoshio wrote in message ...
>In article <7f3khe$lb2$1...@news.kyoto-inet.or.jp>,
> "近藤妥" <yssk...@mbox.kyoto-inet.or.jp> writes:
>
>> 整数の演算後、オーバーフローを判定する方法は、あるのですか?
>> 勿論、ライブラリーレベルでもかまいません。
>
>演算 *後* では遅いと思いますが、、、
>
>符号付き型の場合、演算を行なう前に判定しておかないと、オーバーフ
>ローが起きた場合は未定義動作になります。
と言う事は、演算後のオーバーフローチェックは無理と言う事ですね。
というか、アセンブラ(x86系)なら、演算後オーバーフローをフラグレジスタ
のチェックで行えますよね。こんな方法で無いのか、知りたかったのです。
今は、doubleなどの型で先に計算してオーバーフローしないか確認後に、l
ong型の変数の演算を行っています。
インラインアセンブラをつかって、フラグのオーバーフローフラグを調べるのは?
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
大日向大地 Daichi OBINATA
Obinater , D.Obinata , だいち
ICQ: 27845913
fwic...@mb.infoweb.ne.jp HOME
http://village.infoweb.ne.jp/~fwic0625/ もののあはれ
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
Daichi Obinata wrote in message <7f9bg0$h6f$1...@nw031.infoweb.ne.jp>...
>
>> 整数の演算後、オーバーフローを判定する方法は、あるのですか?
>> 勿論、ライブラリーレベルでもかまいません。
>
>
>インラインアセンブラをつかって、フラグのオーバーフローフラグを調べるのは?
これだと、完全にCPU依存になってしまいますよね。
こえは、ボツです。
ごめんなさい。
> >インラインアセンブラをつかって、フラグのオーバーフローフラグを調べるのは?
>
> これだと、完全にCPU依存になってしまいますよね。
> こえは、ボツです。
オーバーフローした後にそれを検出するというのがそもそもCPUに依存してる
んですから、その検出にCPU依存の手段を使うのがダメと言うのは矛盾してま
す。
オーバーフローしたらトラップが起きるマシンやオーバーフローフラグの無い
マシンだってあるんですよ。x86程度しか考慮してないならすなおにx86のアセ
ンブラを使えば良いじゃないですか。
前田敦司
そんなことありません。
でも、オーバーフローのチェックにどれくらいコスト(時間)をか
けてよいかが明示されていないとどう答えていいんだか難しいで
すね。
どれだけ時間をかけてもいいんだとして、どの演算後のオーバー
フローを知りたいか、符号つきの計算か否かなど、いくつか条件
がわかればそれぞれについて、判定する方法はあるでしょう。
--
/ 青木和麻呂(あおきかずまろ)
/ E-mail: ma...@isl.ntt.co.jp
MAEDA Atusi wrote in message ...
x86のアセンブラしか知らないので、馬鹿な事を書いてしまいました。
すみません。
> でわ、どうしても整数のオーバーフローをチェックしたければ、doubleで前
> もって計算して、オーバーフローの可能性が無いかをチェックするしかないのですね
> ?
doubleで、というのはちょっと良く分かりません。intで表せる範囲がdouble
の仮数部のそれより狭いことを仮定すると言うことでしょうか? そういう仮定
をして良いのならlongやlong longを使って良い気がしますが。
よく意図が分かりませんが、intとlong(あるいはshortとlongなど)を使って、
intの演算がオーバーフローしていない事をlongで確かめる、というのが一番
確実ではないのでしょうか。(で、どの整数型を使うかはcompile時に
configureするとか。)
なるべく長い整数型に付いてチェックしたいのなら、まあ、片山さんがおっしゃっ
た通り、「2の補数」くらいはしょうがないので前提にして、
「2つの数が同符号で、加算の結果がそれと違う符号」
という条件をうまくコーディングするのが妥当では。
前田敦司
議論の本筋から外れて申し訳ないのですが。
> > >インラインアセンブラをつかって、フラグのオーバーフローフラグを調べるのは?
> >
> > これだと、完全にCPU依存になってしまいますよね。
> > こえは、ボツです。
>
> オーバーフローした後にそれを検出するというのがそもそもCPUに依存してる
> んですから、その検出にCPU依存の手段を使うのがダメと言うのは矛盾してま
> す。
文脈から判断すると、特定の処理系に完全に依存するインラインアセンブラと
いう手法は使いたくないという意味では ?
マシン語レベルのコードは各CPUに依存するとしても、コンパイラやライブラリに
できる限りCPUの違いを吸収させ、完全互換ではないにせよ、なるべく可搬性の
あるCのコードでオーバーフローを検出する方法はないか、という議論なら矛盾は
ありません。
仮にxがオーバーフローを検出する関数だとし、ほとんどの処理系でxが実装さ
れれば、100%互換は無理でも、xを使えばCPU(やOS)依存度の低いソースが
書けるわけです。
そういう意味ではstatやumaskがこの例のアナロジーになりますかね。
# 個人的には、整数オーバーフローを signal でトラップしてくれる処理系が
# あってもいい、と思う。
# あるいは逆演算して元の数字と一致するかどうか検算するとか (^^;
--
ロキシー @ Love River 彩の国
BASIC等と違ってC言語の場合任意の関数をユーザーが定義できるので、標準
ライブラリとして揃っているかどうかは、無意味ではないでしょうか?
> # 個人的には、整数オーバーフローを signal でトラップしてくれる処理
> # 系があってもいい、と思う。
オーバーフロー自体をエラー扱いにすべきかどうかはケースバイケースなの
で、なんでもかんでもオーバーフローをトラップしてくれては処理速度にも
影響するし、一般的には迷惑だと思います。
> # あるいは逆演算して元の数字と一致するかどうか検算するとか (^^;
加減算ではオーバーフロー起こす場合でも逆演算しても元の値と同じになり
ますので無意味です。
(例)
int=16bit整数(2の補数表示:+32767~-32768)として...
32767(0x7fff)+1(0x0001)=-32768(0x8000)
~~~~~~
↑
とオーバーフローしますが、この結果に逆の計算をしても元も値になります。
-32768(0x8000)-1(0x0001)=32767(0x7fff)
ですから、普通はこれをより大きい型(int→long)に代入して演算して、型の
示せる値の有効範囲内を越えないかどかチェックするということだと思います。
32767(0x00007fff)+1(0x00000001)=+32768(0x00008000)
~~~~~~
↑
演算結果を調べると、+32768は、INT_MAX(+32767)より大なのでオーバー
フロー。
+---------------------------------------------------------------------+
| From : Dairyo Gokan ( 後神 大陵 ) |
| Organization : Studio NAND Co., Ltd. ( スタジオ・ナンド有限会社 ) |
| Adrs : 39-6-102, Nishi-Kameari 3 Katsushika-ku Tokyo, 125-0002 JPN |
| 〒125-0002 東京都葛飾区西亀有3丁目39番6号パールホワイト102 |
| TEL:03-3838-0850 FAX:03-3838-0875 mailto:na...@can.bekkoame.ne.jp |
+---------------------------------------------------------------------+