MENU
273,859

スレッドNo.2183

思ってもない結果に困惑

あるプログラムをPARI/GPで走らせていたところ、どうしてもプログラムが特定の値では
結果をいくら待っても終了せず、その原因を一つずつ潰していたところなんと思ってもいない
次のような計算が行われていたことが判明しました。
この様なことになってしまうのは、私が使っているソフトに限るのでしょうか?
皆さんが使われているソフトでは如何なる結果を返してくるかを教えて欲しい。

gp > for(n=1,20,print(n";"floor(log(10^n)/log(10))))
1;1
2;2
3;2
4;4
5;5
6;5
7;7
8;8
9;9
10;10
11;10
12;11
13;12
14;14
15;14
16;16
17;16
18;18
19;19
20;20

3,6,11,12,13,15,17でこちらの思惑が裏切られてしまいました。

引用して返信編集・削除(未編集)

手元では同様ですね。
PARI は、ひとたび小数を扱うことになると2進数で内部表現するのかな? と思いましたが、ざっとみ、それだけではうまく説明できないような?

? for(n=1,20,print(n";"floor(log(10^n)/log(10))))
1;1
2;2
3;2
4;4
5;5
6;5
7;7
8;8
9;9
10;10
11;10
12;11
13;12
14;14
15;14
16;16
17;16
18;18
19;19
20;20

引用して返信編集・削除(未編集)

JavaScript では以下の通りです。

for (let n = 1; n <= 20; n++) {
console.log(n + ";" + Math.floor(Math.log(Math.pow(10, n)) / Math.log(10)));
}

上を RUN すると
"1;1"
"2;2"
"3;2"
"4;4"
"5;5"
"6;5"
"7;7"
"8;8"
"9;8"
"10;10"
"11;11"
"12;11"
"13;12"
"14;14"
"15;14"
"16;16"
"17;17"
"18;17"
"19;19"
"20;20"

となります。
JavaScript ではたぶん小数点以下は、最寄りの2進数で捉えているので……

引用して返信編集・削除(未編集)

他の計算ソフトでも調査してみた。
*sageMathのソフト
sage: for i in range(21) :print(i,floor(ln(10^i)/ln(10)));
(0, 0)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
(5, 5)
(6, 6)
(7, 7)
(8, 8)
(9, 9)
(10, 10)
(11, 11)
(12, 12)
(13, 13)
(14, 14)
(15, 15)
(16, 16)
(17, 17)
(18, 18)
(19, 19)
(20, 20)
全部上手く走る


*Rubyのソフト
irb(main):001:0> include Math
=> Object
irb(main):012:0> 0.upto(20){|i| print i,";",log(10**i)/log(10),"\n"}
0;0.0
1;1.0
2;2.0
3;2.9999999999999996
4;4.0
5;5.0
6;5.999999999999999
7;7.0
8;8.0
9;8.999999999999998
10;10.0
11;11.0
12;11.999999999999998
13;12.999999999999998
14;14.0
15;14.999999999999998
16;16.0
17;17.0
18;17.999999999999996
19;19.0
20;20.0
3,6,9,12,13,15,18で上手くいかなくなる。



*Maximaのソフト
(%i13) for i :1 thru 20 do
print(float(log(10^i)/log(10)));

1.0" "
2.0" "
3.0" "
4.0" "
5.0" "
6.0" "
7.0" "
8.0" "
8.999999999999998" "
9.999999999999998" "
11.0" "
12.0" "
13.0" "
14.0" "
15.0" "
16.0" "
17.0" "
18.0" "
19.0" "
20.0" "
9,10で難点

引用して返信編集・削除(未編集)

PARI で、床関数を使う前に微量な下駄をはかせましたが 258,259で破綻。

for(n=257,260,print(n";"floor(10^(-36)+log(10^n)/log(10))))

257;257
258;257
259;258
260;260

引用して返信編集・削除(未編集)

PARI にて、
n = 308 までの範囲で微小量を足すテストをしました。
(javascriptだと10^308を超えると途中計算結果に無限大が現れる扱いになったので……PARIではどうなのかわからず、とりあえずです)

微小量としては、2 ^{-119}と2 ^{- 120} とのあいだに分水嶺があります。以下。

? i = -120; for(n = 1, 308, if(n == floor(2^i + log(10^n)/log(10)), next, print(n, ";", floor(2^i + log(10^n)/log(10))) ) ); print("END")
 
上を走らせると

258;257
259;258
265;264
266;265
271;270
272;271
277;276
278;277
283;282
284;283
290;289
291;290
296;295
297;296
302;301
303;302
308;307
END
 
となり

? i = -119; for(n = 1, 308, if(n == floor(2^i + log(10^n)/log(10)), next, print(n, ";", floor(2^i + log(10^n)/log(10))) ) ); print("END")

上を走らせると
 
END

となります。

引用して返信編集・削除(編集済: 2024年09月22日 22:09)

このスレッドに返信

ロケットBBS

Page Top