さまざまな言語で数値計算
Only Do What Only You Can Do
対数関数 (連分数展開)
連分数展開で $ \log x $ を求めます.
VBScript
Option Explicit Dim i For i = 1 To 20 Dim x: x = i / 5.0 '標準の対数関数 Dim d1: d1 = Log(x) '自作の対数関数 Dim d2: d2 = myLog(x - 1, 27, 0.0) '27:必要な精度が得られる十分大きな奇数 '標準関数との差異 WScript.StdOut.Write Right(Space(5) & FormatNumber(x, 2, -1, 0, 0), 5) & " : " WScript.StdOut.Write Right(Space(13) & FormatNumber(d1, 10, -1, 0, 0), 13) & " - " WScript.StdOut.Write Right(Space(13) & FormatNumber(d2, 10, -1, 0, 0), 13) & " = " WScript.StdOut.Write Right(Space(13) & FormatNumber(d1 - d2, 10, -1, 0, 0), 13) & vbNewLine Next '自作の対数関数 Private Function myLog(ByVal x, ByVal n, ByVal t) Dim n2: n2 = n Dim x2: x2 = x If (n > 3) Then If (n Mod 2 = 0) Then n2 = 2 End If x2 = x * (n \ 2) End If t = x2 / (n2 + t) If (n <= 2) Then myLog = x / (1 + t) Else myLog = myLog(x, n - 1, t) End If End Function
Z:\>cscript //nologo 0507.vbs 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
JScript
for (var i = 1; i <= 20; i++) { var x = i / 5.0; // 標準の対数関数 var d1 = Math.log(x); // 自作の対数関数 var d2 = myLog(x - 1, 27, 0.0); // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 WScript.StdOut.Write((" " + x.toFixed(2) ).slice(-5) + " : "); WScript.StdOut.Write((" " + d1.toFixed(10) ).slice(-13) + " - "); WScript.StdOut.Write((" " + d2.toFixed(10) ).slice(-13) + " = "); WScript.StdOut.Write((" " + (d1 - d2).toFixed(10)).slice(-13) + "\n" ); } // 自作の対数関数 function myLog(x, n, t) { var n2 = n; var x2 = x; if (n > 3) { if (n % 2 == 0) n2 = 2; x2 = x * parseInt(n / 2); } t = x2 / (n2 + t); if (n <= 2) return x / (1 + t); else return myLog(x, --n, t); }
Z:\>cscript //nologo 0507.js 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
PowerShell
# 自作の対数関数 function myLog($x, $n, $t) { $n2 = $n $x2 = $x if ($n -gt 3) { if ($n % 2 -eq 0) { $n2 = 2 } $x2 = $x * [Math]::Floor($n / 2) } $t = $x2 / ($n2 + $t) if ($n -le 2) { $x / (1 + $t) } else { myLog $x ($n - 1) $t } } foreach ($i in 1..20) { $x = $i / 5.0 # 標準の対数関数 $d1 = [Math]::Log($x) # 自作の対数関数 $d2 = myLog ($x - 1) 27 0.0 # 27:必要な精度が得られる十分大きな奇数 # 標準関数との差異 Write-Host ([string]::format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", $x, $d1, $d2, $d1 - $d2)) }
Z:\>powershell -file 0507.ps1 0.20 : -1.6094379124 - -1.6094379124 = 0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = 0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = 0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = 0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = 0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = 0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = 0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = 0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = 0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = 0.0000000000
Perl
# 自作の対数関数 sub myLog { my ($x, $n, $t) = @_; $n2 = $n; $x2 = $x; if ($n > 3) { if ($n % 2 == 0) { $n2 = 2; } $x2 = $x * int($n / 2); } $t = $x2 / ($n2 + $t); if ($n <= 2) { $x / (1 + $t); } else { myLog($x, --$n, $t); } } for $i (1..20) { $x = $i / 5.0; # 標準の対数関数 $d1 = log($x); # 自作の対数関数 $d2 = myLog($x - 1, 27, 0.0); # 27:必要な精度が得られる十分大きな奇数 # 標準関数との差異 printf("%5.2f : %13.10f - %13.10f = %13.10f\n", $x, $d1, $d2, $d1 - $d2); }
Z:\>perl 0507.pl 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
PHP
<?php # 自作の対数関数 function myLog($x, $n, $t) { $n2 = $n; $x2 = $x; if ($n > 3) { if ($n % 2 == 0) $n2 = 2; $x2 = $x * (int)($n / 2); } $t = $x2 / ($n2 + $t); if ($n <= 2) return $x / (1 + $t); else return myLog($x, --$n, $t); } foreach (range(1, 20) as $i) { $x = $i / 5.0; # 標準の対数関数 $d1 = log($x); # 自作の対数関数 $d2 = myLog($x - 1, 27, 0.0); # 27:必要な精度が得られる十分大きな奇数 # 標準関数との差異 printf("%5.2f : %13.10f - %13.10f = %13.10f\n", $x, $d1, $d2, $d1 - $d2); } ?>
Z:\>php 0507.php 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
Python
# coding: Shift_JIS import math # 自作の対数関数 def myLog(x, n, t): n2 = n x2 = x if (n > 3): if (n % 2 == 0): n2 = 2 x2 = x * int(n / 2) t = x2 / (n2 + t) if (n <= 2): return x / (1 + t) else: return myLog(x, n - 1, t) for i in range(1, 21): x = i / 5.0 # 標準の対数関数 d1 = math.log(x) # 自作の対数関数 d2 = myLog(x - 1, 27, 0.0) # 27:必要な精度が得られる十分大きな奇数 # 標準関数との差異 print "%5.2f : %13.10f - %13.10f = %13.10f" % (x, d1, d2, d1 - d2)
Z:\>python 0507.py 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
Ruby
# 自作の対数関数 def myLog(x, n, t) n2 = n x2 = x if (n > 3) if (n % 2 == 0) n2 = 2 end x2 = x * (n / 2) end t = x2 / (n2 + t) if (n <= 2) x / (1 + t); else myLog(x, n - 1, t) end end (1..20).each do |i| x = i / 5.0 # 標準の対数関数 d1 = Math.log(x) # 自作の対数関数 d2 = myLog(x - 1, 27, 0.0) # 27:必要な精度が得られる十分大きな奇数 # 標準関数との差異 printf("%5.2f : %13.10f - %13.10f = %13.10f\n", x, d1, d2, d1 - d2) end
Z:\>ruby 0507.rb 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
Groovy
Pascal
Program Pas0507(arg); {$MODE delphi} uses SysUtils, Math; // 自作の対数関数 function myLog(x:Double; n:Integer; t:Double):Double; var n2 :Integer; x2 :Double; begin n2 := n; x2 := x; if (n > 3) then begin if (n Mod 2 = 0) then n2 := 2; x2 := x * (n Div 2); end; t := x2 / (n2 + t); if (n <= 2) then result := x / (1 + t) else result := myLog(x, n - 1, t); end; var i: Integer; x: Double; d1: Double; d2: Double; begin for i := 1 to 20 do begin x := i / 5.0; // 標準の対数関数 d1 := Ln(x); // 自作の対数関数 d2 := myLog(x - 1, 27, 0.0); // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 writeln(format('%5.2f : %13.10f - %13.10f = %13.10f', [x, d1, d2, d1 - d2])); end; end.
Z:\>fpc Pas0507.pp -v0 Free Pascal Compiler version 2.6.2 [2013/02/12] for i386 Copyright (c) 1993-2012 by Florian Klaempfl and others Z:\>Pas0507 0.20 : -1.6094379124 - -1.6094379124 = 0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = 0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = 0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = 0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = 0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = 0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = 0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = 0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = 0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = 0.0000000000
Ada
VB.NET
Module VB0507 Public Sub Main() For i As Integer = 1 To 20 Dim x As Double = i / 5.0 '標準の対数関数 Dim d1 As Double = Math.Log(x) '自作の対数関数 Dim d2 As Double = myLog(x - 1, 27, 0.0) '27:必要な精度が得られる十分大きな奇数 '標準関数との差異 Console.WriteLine(String.Format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", x, d1, d2, d1 - d2)) Next End Sub '自作の対数関数 Private Function myLog(ByVal x As Double, ByVal n As Integer, ByVal t As Double) As Double Dim n2 As Integer = n Dim x2 As Double = x If (n > 3) Then If (n Mod 2 = 0) Then n2 = 2 End If x2 = x * (n \ 2) End If t = x2 / (n2 + t) If (n <= 2) Then Return x / (1 + t) Else Return myLog(x, n - 1, t) End If End Function End Module
Z:\>vbc -nologo VB0507.vb Z:\>VB0507 0.20 : -1.6094379124 - -1.6094379124 = 0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = 0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = 0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = 0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = 0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = 0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = 0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = 0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = 0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = 0.0000000000
C#
using System; public class CS0507 { public static void Main() { for (int i = 1; i <= 20; i++) { double x = i / 5.0; // 標準の対数関数 double d1 = Math.Log(x); // 自作の対数関数 double d2 = myLog(x - 1, 27, 0.0); // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 Console.WriteLine(string.Format("{0,5:F2} : {1,13:F10} - {2,13:F10} = {3,13:F10}", x, d1, d2, d1 - d2)); } } // 自作の対数関数 private static double myLog(double x, int n, double t) { int n2 = n; double x2 = x; if (n > 3) { if (n % 2 == 0) n2 = 2; x2 = x * (n / 2); } t = x2 / (n2 + t); if (n <= 2) return x / (1 + t); else return myLog(x, --n, t); } }
Z:\>csc -nologo CS0507.cs Z:\>CS0507 0.20 : -1.6094379124 - -1.6094379124 = 0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = 0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = 0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = 0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = 0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = 0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = 0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = 0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = 0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = 0.0000000000
Java
public class Java0507 { public static void main(String []args) { for (int i = 1; i <= 20; i++) { double x = i / 5.0; // 標準の対数関数 double d1 = Math.log(x); // 自作の対数関数 double d2 = myLog(x - 1, 27, 0.0); // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 System.out.println(String.format("%5.2f : %13.10f - %13.10f = %13.10f", x, d1, d2, d1 - d2)); } } // 自作の対数関数 private static double myLog(double x, int n, double t) { int n2 = n; double x2 = x; if (n > 3) { if (n % 2 == 0) n2 = 2; x2 = x * (n / 2); } t = x2 / (n2 + t); if (n <= 2) return x / (1 + t); else return myLog(x, --n, t); } }
Z:\>javac Java0507.java Z:\>java Java0507 0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
C++
#include <iostream> #include <iomanip> #include <math> using namespace std; double myLog(double x, int n, double t); int main() { for (int i = 1; i <= 20; i++) { double x = i / 5.0; // 標準の対数関数 double d1 = log(x); // 自作の対数関数 double d2 = myLog(x - 1, 27, 0.0); // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 cout << setw(5) << fixed << setprecision(2) << x << ":"; cout << setw(14) << fixed << setprecision(10) << d1 << " - "; cout << setw(14) << fixed << setprecision(10) << d2 << " = "; cout << setw(14) << fixed << setprecision(10) << d1 - d2 << endl; } return 0; } // 自作の対数関数 double myLog(double x, int n, double t) { int n2 = n; double x2 = x; if (n > 3) { if (n % 2 == 0) n2 = 2; x2 = x * (n / 2); } t = x2 / (n2 + t); if (n <= 2) return x / (1 + t); else return myLog(x, --n, t); }
Z:\>bcc32 CP0507.cpp Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland CP0507.cpp: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Z:\>CP0507 0.20: -1.6094379124 - -1.6094379124 = 0.0000000000 0.40: -0.9162907319 - -0.9162907319 = 0.0000000000 0.60: -0.5108256238 - -0.5108256238 = -0.0000000000 0.80: -0.2231435513 - -0.2231435513 = 0.0000000000 1.00: 0.0000000000 - 0.0000000000 = 0.0000000000 1.20: 0.1823215568 - 0.1823215568 = -0.0000000000 1.40: 0.3364722366 - 0.3364722366 = -0.0000000000 1.60: 0.4700036292 - 0.4700036292 = 0.0000000000 1.80: 0.5877866649 - 0.5877866649 = 0.0000000000 2.00: 0.6931471806 - 0.6931471806 = 0.0000000000 2.20: 0.7884573604 - 0.7884573604 = 0.0000000000 2.40: 0.8754687374 - 0.8754687374 = -0.0000000000 2.60: 0.9555114450 - 0.9555114450 = 0.0000000000 2.80: 1.0296194172 - 1.0296194172 = 0.0000000000 3.00: 1.0986122887 - 1.0986122887 = 0.0000000000 3.20: 1.1631508098 - 1.1631508098 = 0.0000000000 3.40: 1.2237754316 - 1.2237754316 = 0.0000000000 3.60: 1.2809338455 - 1.2809338455 = 0.0000000000 3.80: 1.3350010667 - 1.3350010667 = 0.0000000000 4.00: 1.3862943611 - 1.3862943611 = 0.0000000000
Objective-C
#import <Foundation/Foundation.h> double myLog(double x, int n, double t); int main() { int i; for (i = 1; i <= 20; i++) { double x = i / 5.0; // 標準の対数関数 double d1 = log(x); // 自作の対数関数 double d2 = myLog(x - 1, 27, 0.0); // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 printf("%+04.2f : %+013.10f - %+013.10f = %+13.10f\n", x, d1, d2, d1 - d2); } return 0; } // 自作の対数関数 double myLog(double x, int n, double t) { int n2 = n; double x2 = x; if (n > 3) { if (n % 2 == 0) n2 = 2; x2 = x * (n / 2); } t = x2 / (n2 + t); if (n <= 2) return x / (1 + t); else return myLog(x, --n, t); }
Compiling the source code.... $gcc `gnustep-config --objc-flags` -L/usr/GNUstep/System/Library/Libraries -lgnustep-base main.m -o demo -lm -pthread -lgmpxx -lreadline 2>&1 Executing the program.... $demo +0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 +0.40 : -0.9162907319 - -0.9162907319 = +0.0000000000 +0.60 : -0.5108256238 - -0.5108256238 = +0.0000000000 +0.80 : -0.2231435513 - -0.2231435513 = +0.0000000000 +1.00 : +0.0000000000 - +0.0000000000 = +0.0000000000 +1.20 : +0.1823215568 - +0.1823215568 = -0.0000000000 +1.40 : +0.3364722366 - +0.3364722366 = +0.0000000000 +1.60 : +0.4700036292 - +0.4700036292 = +0.0000000000 +1.80 : +0.5877866649 - +0.5877866649 = +0.0000000000 +2.00 : +0.6931471806 - +0.6931471806 = +0.0000000000 +2.20 : +0.7884573604 - +0.7884573604 = +0.0000000000 +2.40 : +0.8754687374 - +0.8754687374 = +0.0000000000 +2.60 : +0.9555114450 - +0.9555114450 = -0.0000000000 +2.80 : +1.0296194172 - +1.0296194172 = -0.0000000000 +3.00 : +1.0986122887 - +1.0986122887 = -0.0000000000 +3.20 : +1.1631508098 - +1.1631508098 = -0.0000000000 +3.40 : +1.2237754316 - +1.2237754316 = -0.0000000000 +3.60 : +1.2809338455 - +1.2809338455 = -0.0000000000 +3.80 : +1.3350010667 - +1.3350010667 = -0.0000000000 +4.00 : +1.3862943611 - +1.3862943611 = -0.0000000000
D
Go
Scala
対話型実行環境を起動
Z:\>scala Welcome to Scala version 2.10.2 (Java HotSpot(TM) Client VM, Java 1.7.0_21). Type in expressions to have them evaluated. Type :help for more information.
連分数展開で log x を求める
// 自作の対数関数 def myLog(x:Double, n:Int, t:Double):Double = { var n2 = n var x2 = x if (n > 3) { if (n % 2 == 0) n2 = 2 x2 = x * (n / 2) } val t2 = x2 / (n2 + t) if (n <= 2) x / (1 + t2) else myLog(x, n - 1, t2) }
(1 to 20). map(_ / 5.0). foreach { x => // 標準の対数関数 val d1 = Math.log(x) // 自作の対数関数 val d2 = myLog(x - 1, 27, 0.0) // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 System.out.println("%5.2f : %13.10f - %13.10f = %13.10f".format(x, d1, d2, d1 - d2)) }
0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
終了
scala> :quit
F#
対話型実行環境を起動
Z:\>fsi Microsoft (R) F# 2.0 Interactive build 4.0.40219.1 Copyright (c) Microsoft Corporation. All Rights Reserved. For help type #help;;
連分数展開で log x を求める
// 自作の対数関数 let rec myLog (x:double) (n:int) (t:double):double = let mutable n2 = n let mutable x2 = x if n > 3 then if n % 2 = 0 then n2 <- 2 x2 <- x * (double (n / 2)) let t2 = x2 / ((double n2) + t) if n <= 2 then x / (1.0 + t2) else myLog x (n - 1) t2
[1..20] |> List.map (fun n -> (double n) / 5.0) |> List.iter (fun x -> // 標準の対数関数 let d1 = System.Math.Log(x) // 自作の対数関数 let d2 = (myLog (x - 1.0) 27 0.0) // 27:必要な精度が得られる十分大きな奇数 // 標準関数との差異 printfn "%5.2f : %13.10f - %13.10f = %13.10f" x d1 d2 (d1 - d2) )
0.20 : -1.6094379124 - -1.6094379124 = 0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = 0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = 0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = 0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = 0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = 0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = 0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = 0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = 0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = 0.0000000000 val it : unit = ()
終了
> #quit;;
Clojure
対話型実行環境を起動
Z:\>java -cp C:\ProgramFiles\clojure-1.5.1\clojure-1.5.1.jar clojure.main Clojure 1.5.1
連分数展開で log x を求める
;自作の対数関数 (defn myLog [x n t] (do (def n2 (if (zero? (rem n 2)) 2 n)) (def n3 (if (> n 3) n2 n)) (def x2 (if (> n 3) (* x (quot n 2)) x)) (def t2 (/ x2 (+ n3 t))) (if (<= n 2) (/ x (+ 1.0 t2)) (myLog x (- n 1) t2))))
(doseq [x (map #(/ % 5.0) (range 1 21))] (do ;標準の対数関数 (def d1 (. Math log x)) ;自作の対数関数 (def d2 (myLog (- x 1.0) 27 0.0)) ;27:必要な精度が得られる十分大きな奇数 ;標準関数との差異 (println (format "%5.2f : %13.10f - %13.10f = %13.10f" x d1 d2 (- d1 d2)))))
0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000 nil
終了
user=> (. System exit 0)
Haskell
対話型実行環境を起動
Z:\>ghci GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done.
連分数展開で log x を求める
-- 自作の対数関数 myLog::Double->Int->Double->Double myLog x n t = let n2 = if rem n 2 == 0 then 2 else n n3 = if n > 3 then n2 else n x2 = if n > 3 then x * (fromIntegral (div n 2)) else x t2 = x2 / ((fromIntegral n3) + t) in if n <= 2 then x / (1.0 + t2) else myLog x (n - 1) t2
import Text.Printf import Control.Monad forM_ ( map (\n -> (fromIntegral n) / 5.0) $ [1..20::Int] ) $ \x -> do -- 標準の対数関数 let d1 = log(x) -- 自作の対数関数 let d2 = (myLog (x - 1.0) 27 0.0) -- 27:必要な精度が得られる十分大きな奇数 -- 標準関数との差異 printf "%5.2f : %13.10f - %13.10f = %13.10f\n" x d1 d2 (d1- d2)
0.20 : -1.6094379124 - -1.6094379124 = -0.0000000000 0.40 : -0.9162907319 - -0.9162907319 = 0.0000000000 0.60 : -0.5108256238 - -0.5108256238 = 0.0000000000 0.80 : -0.2231435513 - -0.2231435513 = 0.0000000000 1.00 : 0.0000000000 - 0.0000000000 = 0.0000000000 1.20 : 0.1823215568 - 0.1823215568 = -0.0000000000 1.40 : 0.3364722366 - 0.3364722366 = 0.0000000000 1.60 : 0.4700036292 - 0.4700036292 = 0.0000000000 1.80 : 0.5877866649 - 0.5877866649 = 0.0000000000 2.00 : 0.6931471806 - 0.6931471806 = 0.0000000000 2.20 : 0.7884573604 - 0.7884573604 = 0.0000000000 2.40 : 0.8754687374 - 0.8754687374 = 0.0000000000 2.60 : 0.9555114450 - 0.9555114450 = -0.0000000000 2.80 : 1.0296194172 - 1.0296194172 = -0.0000000000 3.00 : 1.0986122887 - 1.0986122887 = -0.0000000000 3.20 : 1.1631508098 - 1.1631508098 = -0.0000000000 3.40 : 1.2237754316 - 1.2237754316 = -0.0000000000 3.60 : 1.2809338455 - 1.2809338455 = -0.0000000000 3.80 : 1.3350010667 - 1.3350010667 = -0.0000000000 4.00 : 1.3862943611 - 1.3862943611 = -0.0000000000
終了
Prelude> :quit Leaving GHCi.