らでぃっくすを底としちゃうかもしれない その3

ついに分かった。
とりあえず、おさらいしておこう:

  1. 常用対数は底が 10 な log。
  2. 自然対数は底が E な log(ln*1 とも)。

で、底が b な lob を logb とすると logb x は:

log(x) / log(b)

で求められる。
log8 19 を計算してみよう。

foo = Math.log(19) / Math.log(8)
bar = Math.log(19, 8)

p foo == bar
p foo - bar

printf("%0.20f\n", foo)
printf("%0.20f\n", bar)

違いが分からなかったんで、20桁まで表示してやっとわかったぜ…

false
2.22044604925031e-16
1.41597583781452862617
1.41597583781452840412

10e-16 = 10 フェムト
たったの 10 須臾くらいなんだ!
…といいたいとこだが、流石に何度も誤差ったりするんだろうか、と不安になったのでもーちょいやってみた。

21.times do |unused|
  base = rand(100) + 2
  rsv  = rand(100) + 2

  left = Math.log( rsv ) / Math.log( base )
  right = Math.log( rsv, base )

  printf( "log( %3d ) / log( %3d ) = %0.20f\n", rsv, base, left )
  printf( "log( %3d, %3d )         = %0.20f\n", rsv, base, right )
  puts "#{left - right}"
  puts
end

だいだいあってる、ってことで。

>

log(  85 ) / log(  87 ) = 0.99479235542999178143
log( 85, 87 ) = 0.99479235542999178143
0.0

log( 82 ) / log( 31 ) = 1.28326606503035800522
log( 82, 31 ) = 1.28326606503035800522
0.0

log( 57 ) / log( 38 ) = 1.11146543072911385686
log( 57, 38 ) = 1.11146543072911385686
0.0

log( 87 ) / log( 62 ) = 1.08208449301700904144
log( 87, 62 ) = 1.08208449301700904144
0.0

log( 38 ) / log( 57 ) = 0.89971309260064591395
log( 38, 57 ) = 0.89971309260064591395
0.0

log( 30 ) / log( 94 ) = 0.74861912877305913927
log( 30, 94 ) = 0.74861912877305902825
1.11022302462516e-16

log( 27 ) / log( 20 ) = 1.10017737402625392917
log( 27, 20 ) = 1.10017737402625392917
0.0

log( 16 ) / log( 65 ) = 0.66419058486375137651
log( 16, 65 ) = 0.66419058486375126549
1.11022302462516e-16

log( 32 ) / log( 42 ) = 0.92724511707684442730
log( 32, 42 ) = 0.92724511707684453832
-1.11022302462516e-16

log( 85 ) / log( 22 ) = 1.43726633442498408222
log( 85, 22 ) = 1.43726633442498408222
0.0

log( 55 ) / log( 97 ) = 0.87597516084906212885
log( 55, 97 ) = 0.87597516084906212885
0.0

log( 22 ) / log( 73 ) = 0.72044555967902657034
log( 22, 73 ) = 0.72044555967902657034
0.0

log( 79 ) / log( 52 ) = 1.10584113855566901208
log( 79, 52 ) = 1.10584113855566901208
0.0

log( 41 ) / log( 83 ) = 0.84039511634614849633
log( 41, 83 ) = 0.84039511634614860736
-1.11022302462516e-16

log( 68 ) / log( 34 ) = 1.19656163223282252517
log( 68, 34 ) = 1.19656163223282274721
-2.22044604925031e-16

log( 79 ) / log( 19 ) = 1.48396617602990565921
log( 79, 19 ) = 1.48396617602990565921
0.0

log( 36 ) / log( 2 ) = 5.16992500144231215131
log( 36, 2 ) = 5.16992500144231215131
0.0

log( 100 ) / log( 55 ) = 1.14918574850694366063
log( 100, 55 ) = 1.14918574850694366063
0.0

log( 58 ) / log( 80 ) = 0.92661303754229806806
log( 58, 80 ) = 0.92661303754229795704
1.11022302462516e-16

log( 17 ) / log( 89 ) = 0.63119689604646878056
log( 17, 89 ) = 0.63119689604646866954
1.11022302462516e-16

log( 33 ) / log( 45 ) = 0.91852313433688392852
log( 33, 45 ) = 0.91852313433688381750
1.11022302462516e-16

*1:math.h だと log で常用対数は log10 だった