十進BASICのバグだとは思いますが...

 投稿者:しばっち  投稿日:2022年 1月 1日(土)19時05分44秒
  WINDOWS版十進BASIC ver. 7.8.5.6で下記のプログラムを
2進モード、複素数モードで実行するとI=171でエラーとなり実行が止まります。
10進モードだとI=70で止まります。
1000桁モードではI=453で止まります。

LET A=1
FOR I=2 TO 500
   LET A=A*I
   PRINT I;A
NEXT I
END

次に下記のようにプログラムを変更して2進モード、複素数モードで実行すると
I=170以降は同じ値が表示されます。

ですが10進モードだとそのまま計算し続けます。
しかもMAXNUM(1E99)をはるかに超えています。

WHEN EXCEPTION IN文がエラーによる停止を抑止したため、MAXNUMを超えて計算しています。
また、MAXNUM値を超えた数値が正しく判定できています。

これは明らかに十進BASICのバグだとは思いますが、2進モード(複素数モード)での限界(1.79769313486232E308)を超えていますので
指数表記ではありますが、正しく計算できているようなので超巨大数の計算に利用できそうです。(巨大数の計算には有理数モードがありますが...)

但し、MAXNUM値を大幅に超えていますので何らかの不具合を起こす可能性があるかもしれません。
(実際にどこまで計算できるのかは試しておりません。2000の階乗までは問題ない!?)

2進モード(複素数モード)ではIEEE754による数値表現で限界値があるのはわかりますが
10進モードでの数値表現(どんなものかよくわかりませんが)では、まだまだ計算可能ということだと思います。


1000桁モードではI=453でMAXNUMを超えています。
I=819で小数点以下2000桁を超えています。
I=820から指数表示に変わりますがそのまま計算し続けてます。

LET A=1
FOR I=2 TO 2000

   WHEN EXCEPTION IN
      LET A=A*I
   USE
   END WHEN

   PRINT I;
   IF MAXNUM<A THEN PRINT "TRUE"; ELSE PRINT "FALSE";
   PRINT A
NEXT I
END

       2進モード(複素数モード)での実行(一部のみ)

165 FALSE 5.42391066613159E295
166 FALSE 9.00369170577843E297
167 FALSE 1.503616514865E300
168 FALSE 2.5260757449732E302
169 FALSE 4.2690680090047E304
170 FALSE 7.25741561530799E306
171 FALSE 7.25741561530799E306
172 FALSE 7.25741561530799E306
173 FALSE 7.25741561530799E306

       10進モードでの実行(一部のみ)

65 FALSE 8.24765059208253E90
66 FALSE 5.44344939077447E92
67 FALSE 3.64711109181889E94
68 FALSE 2.48003554243685E96
69 FALSE 1.71122452428143E98
70 TRUE 1.197857166997E100
71 TRUE 8.50478588567871E101
72 TRUE 6.12344583768867E103
73 TRUE 4.47011546151273E105
74 TRUE 3.30788544151942E107
75 TRUE 2.48091408113956E109

1997 TRUE 4.151569143494E5725
1998 TRUE 8.29483514870102E5728
1999 TRUE 1.65813754622533E5732
2000 TRUE 3.31627509245067E5735


ちなみに下記のようにした場合は
2進モード、複素数モードで実行するとI=178以降で0になります。

10進モードではI=70以降で0になります。
(I=70以降も0にはならずにずっと指数表示が続くかと思ったのですが...)

1000桁モードではI=456で小数点以下2000桁を超えていますが
I=457で突然0になります。これは何らかの処理により0が代入されたものと思いますが
この挙動はいささか不自然にも思えます。

LET A=1
FOR I=2 TO 500
   LET A=A/I
   PRINT I;A
NEXT I
END
 

Re: 十進BASICのバグだとは思いますが...

 投稿者:SHIRAISHI Kazuo  投稿日:2022年 1月 2日(日)08時13分51秒
  10進モードの十進演算ルーチンは指数部をかなり大きく取っています。
べき乗の計算精度がほぼ確実と考えられる範囲をもとにMAXNUMとEPS(0)を定めています。
Full BASICの十進演算は,数値式と数値変数は別物です。
MAXNUMとEPS(0)は,数値変数の精度からきまる定数です。
十進BASICだと,数値式の途中でMAXNUMを超えるような計算も可能です。

10 LET x=MAXNUM
20 PRINT (MAXNUM*1000)/10000
30 END
数値変数にEPS(0)より小さい正の数を代入すると,変数の値は0になります。
十進BASICでは,数値式の中でそれより小さい数も扱えます。
10 LET x=EPS(0)
20 PRINT (x/100)*1000
30 END

10進1000桁モードのEPS(0)は1E-1017です。
10 OPTION ARITHMETIC DECIMAL_HIGH
20 PRINT USING "#.##^^^^^^":EPS(0)
30 END

ただし,MAXNUMより大きい数やEPS(0)より小さい数を数値変数に保持できるのは,十進BASICのバグかも知れません。








> WINDOWS版十進BASIC ver. 7.8.5.6で下記のプログラムを
> 2進モード、複素数モードで実行するとI=171でエラーとなり実行が止まります。
> 10進モードだとI=70で止まります。
> 1000桁モードではI=453で止まります。
>
> LET A=1
> FOR I=2 TO 500
>    LET A=A*I
>    PRINT I;A
> NEXT I
> END
>
> 次に下記のようにプログラムを変更して2進モード、複素数モードで実行すると
> I=170以降は同じ値が表示されます。
>
> ですが10進モードだとそのまま計算し続けます。
> しかもMAXNUM(1E99)をはるかに超えています。
>
> WHEN EXCEPTION IN文がエラーによる停止を抑止したため、MAXNUMを超えて計算しています。
> また、MAXNUM値を超えた数値が正しく判定できています。
>
> これは明らかに十進BASICのバグだとは思いますが、2進モード(複素数モード)での限界(1.79769313486232E308)を超えていますので
> 指数表記ではありますが、正しく計算できているようなので超巨大数の計算に利用できそうです。(巨大数の計算には有理数モードがありますが...)
>
> 但し、MAXNUM値を大幅に超えていますので何らかの不具合を起こす可能性があるかもしれません。
> (実際にどこまで計算できるのかは試しておりません。2000の階乗までは問題ない!?)
>
> 2進モード(複素数モード)ではIEEE754による数値表現で限界値があるのはわかりますが
> 10進モードでの数値表現(どんなものかよくわかりませんが)では、まだまだ計算可能ということだと思います。
>
>
> 1000桁モードではI=453でMAXNUMを超えています。
> I=819で小数点以下2000桁を超えています。
> I=820から指数表示に変わりますがそのまま計算し続けてます。
>
> LET A=1
> FOR I=2 TO 2000
>
>    WHEN EXCEPTION IN
>       LET A=A*I
>    USE
>    END WHEN
>
>    PRINT I;
>    IF MAXNUM<A THEN PRINT "TRUE"; ELSE PRINT "FALSE";
>    PRINT A
> NEXT I
> END
>
>        2進モード(複素数モード)での実行(一部のみ)
>
>  165 FALSE 5.42391066613159E295
>  166 FALSE 9.00369170577843E297
>  167 FALSE 1.503616514865E300
>  168 FALSE 2.5260757449732E302
>  169 FALSE 4.2690680090047E304
>  170 FALSE 7.25741561530799E306
>  171 FALSE 7.25741561530799E306
>  172 FALSE 7.25741561530799E306
>  173 FALSE 7.25741561530799E306
>
>        10進モードでの実行(一部のみ)
>
>  65 FALSE 8.24765059208253E90
>  66 FALSE 5.44344939077447E92
>  67 FALSE 3.64711109181889E94
>  68 FALSE 2.48003554243685E96
>  69 FALSE 1.71122452428143E98
>  70 TRUE 1.197857166997E100
>  71 TRUE 8.50478588567871E101
>  72 TRUE 6.12344583768867E103
>  73 TRUE 4.47011546151273E105
>  74 TRUE 3.30788544151942E107
>  75 TRUE 2.48091408113956E109
>
>  1997 TRUE 4.151569143494E5725
>  1998 TRUE 8.29483514870102E5728
>  1999 TRUE 1.65813754622533E5732
>  2000 TRUE 3.31627509245067E5735
>
>
> ちなみに下記のようにした場合は
> 2進モード、複素数モードで実行するとI=178以降で0になります。
>
> 10進モードではI=70以降で0になります。
> (I=70以降も0にはならずにずっと指数表示が続くかと思ったのですが...)
>
> 1000桁モードではI=456で小数点以下2000桁を超えていますが
> I=457で突然0になります。これは何らかの処理により0が代入されたものと思いますが
> この挙動はいささか不自然にも思えます。
>
> LET A=1
> FOR I=2 TO 500
>    LET A=A/I
>    PRINT I;A
> NEXT I
> END
>
 

戻る