FACT,PERM,COMB関数のバグ

 投稿者:荒田浩二  投稿日:2009年 8月12日(水)22時27分59秒
  階乗,順列,組合せの組込み関数FACT(x),PERM(n,r),COMB(n,r)に不具合を発見したので報告します。

(1) FACT(x)を2進モード,複素数モードで実行した場合、xが小数のとき例外とならず誤った値を返す。
100 OPTION ARITHMETIC NATIVE
110 FOR x=-1 TO 4
120    WHEN EXCEPTION IN
130       PRINT x;FACT(x) ! 整数では問題ない
140    USE
150    END WHEN
160 NEXT x
170 PRINT
180 FOR x=-1 TO 4.0001 STEP 0.1
190    WHEN EXCEPTION IN
200       PRINT x;FACT(x) ! x<-0.5では例外が発生
210    USE
220    END WHEN
230 NEXT x
240 END
上記プログラムを10進15桁,1000桁,有理数の各モードで実行した場合、xが小数のときは例外が発生する。


(2) PERM(n,r);COMB(n,r)を2進モード,複素数モードで実行した場合、rが小数のとき例外とならずrを整数に丸めて得た値を返す。
400 OPTION ARITHMETIC NATIVE
410 LET n=6
420 FOR r=-2 TO 3.0001 STEP 0.1
430    WHEN EXCEPTION IN
440       PRINT n;r;" ---> ";PERM(n,r);COMB(n,r) ! r<-0.5では例外が発生
450    USE
460    END WHEN
470 NEXT r
480 END
上記プログラムを10進15桁,1000桁,有理数の各モードで実行した場合、rが小数のときは例外が発生する。


(3) PERM(n,r),COMB(n,r)でnが負数,小数のとき例外とならず誤った値を返す。
600 LET r=3
610 FOR n=-4 TO 5 STEP 0.2
620    WHEN EXCEPTION IN
630       PRINT n;r;" ===> ";PERM(n,r);COMB(n,r)
640    USE
650    END WHEN
660 NEXT n
670 END
 

Re: FACT,PERM,COMB関数のバグ

 投稿者:白石 和夫  投稿日:2009年 8月13日(木)07時45分46秒
  > No.475[元記事へ]

ご報告ありがとうございます。
FACT,PERM,COMBの各組込関数は規格外の機能なので,「定義域外の引数に対する動作は不定」が仕様です。(仕様は未確定ともいえます。)
なお,PERM(n,r)の定義域は,rが正の整数です。nは負数や小数でもかまいません。
PERM(n,r)=n(n-1)(n-2)…(n-r+1) で定義されます。
COMB(n,r)は,nが負整数またはrより大きい整数のとき0になります。
なお,COMB(n,r)=PERM(n,r)/FACT(r)で定義すると都合のよいこともあるのですが,内部の処理の都合でそうならないことがあります。
 

Re: FACT,PERM,COMB関数のバグ

 投稿者:荒田浩二  投稿日:2009年 8月13日(木)19時25分32秒
  > No.476[元記事へ]

ご回答いただきありがとうございます。
WHEN~END WHENの中でFACT関数を使ったところ、10進モードと2進モードでまったく違う結果が出たので、これはバグであろうと思ってしまいました。
どの数値モードでも同じ挙動をするプログラムにするには、これらの関数を使う前に引数の判定をするif文を入れる必要があるようですね。
詳しくご説明していただき理解することができました。ありがとうございました。
 

戻る