home > さまざまな言語で数値計算 > 非線形方程式 >

さまざまな言語で数値計算

Only Do What Only You Can Do

はさみうち法

非線形方程式の解法(はさみうち法)を利用して2の平方根を求める .

考え方は、2分法とほとんど同じ.

1. まず, 条件 $ a < b, f(a) < 0, f(b) > 0 $ を満たす点 $ a, b $ を考えると,
関数 $ f(x) $ の解は, 区間 $ (a,b) $ の中に存在する.

2. 次に, 点 $ (a,f(a)) $ と 点 $ (b,f(b)) $ を結ぶ直線と $x$ 軸の交点 を考えると,
$ f(c) < 0 $ であれば, 解は, 区間 $ (c,b) $ の中に存在し,
同様に, $ f(c) > 0 $ であれば, 区間 $ (a,c) $ の中に存在する.

3. この作業を繰り返して, 区間を絞り込んで行くことで解を求める.

※ ちなみに, 区間 $ (a,b) $ とは, 両端を含まない数の集合で, 開区間という.
$ (a,b) = \{x | a < x < b \} $
また, 両端を含む数の集合は, 閉区間という.
$ [a,b] = \{x | a \leq x \leq b \} $

VBScript

Option Explicit

Dim a: a = 1.0
Dim b: b = 2.0
WScript.StdOut.Write Right(Space(12) & FormatNumber(falseposition(a, b), 10, -1, 0, 0), 12) & vbNewLine

Private Function falseposition(ByVal a, ByVal b)
    Dim c
    Do While(True)
        '点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c = (a * f(b) - b * f(a)) / (f(b) - f(a))
        WScript.StdOut.Write Right(Space(12) & FormatNumber(c,          10, -1, 0, 0), 12) & vbTab
        WScript.StdOut.Write Right(Space(12) & FormatNumber(c - Sqr(2), 10, -1, 0, 0), 12) & vbNewLine

        Dim fc: fc = f(c)
        If Abs(fc) < 0.0000000001 Then Exit Do

        If fc < 0 Then
            'f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c
        Else
            'f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c
        End If
    Loop

    falseposition = c
End Function

Private Function f(ByVal x)
    f = x * x - 2.0
End Function
Z:\>cscript //nologo Z:\0902.vbs
1.3333333333    0.0808802290
1.4000000000    0.0142135624
1.4117647059    0.0024488565
1.4137931034    0.0004204589
1.4141414141    0.0000721482
1.4142011834    0.0000123789
1.4142114385    0.0000021239
1.4142131980    0.0000003644
1.4142134999    0.0000000625
1.4142135516    0.0000000107
1.4142135605    0.0000000018
1.4142135621    0.0000000003
1.4142135623    0.0000000001
1.4142135624    0.0000000000
1.4142135624

JScript

var a = 1
var b = 2
WScript.StdOut.Write(("            " + falseposition(a, b).toFixed(10) ).slice(-12) + "\n")

function falseposition(a, b) {
    var c
    while (true) {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c  = (a * f(b) - b * f(a)) / (f(b) - f(a))
        WScript.StdOut.Write(("            " + c.toFixed(10)                  ).slice(-12) + "\t")
        WScript.StdOut.Write(("            " + (c - Math.sqrt(2)).toFixed(10) ).slice(-12) + "\n")

        var fc = f(c)
        if (Math.abs(fc) < 0.0000000001) break

        if (fc < 0){
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c
        } else {
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c
        }
    }
    return c
}

function f(x) {
    return x * x - 2
}
Z:\>cscript //nologo Z:\0902.js
1.3333333333    0.0808802290
1.4000000000    0.0142135624
1.4117647059    0.0024488565
1.4137931034    0.0004204589
1.4141414141    0.0000721482
1.4142011834    0.0000123789
1.4142114385    0.0000021239
1.4142131980    0.0000003644
1.4142134999    0.0000000625
1.4142135516    0.0000000107
1.4142135605    0.0000000018
1.4142135621    0.0000000003
1.4142135623    0.0000000000
1.4142135624    0.0000000000
1.4142135624

PowerShell

function falseposition($a, $b)
{
    while ($true)
    {
        # 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        $c = ($a * (f $b) - $b * (f $a)) / ((f $b) - (f $a))
        Write-Host ([String]::Format("{0,12:F10}`t{1,13:F10}", $c, $c - [Math]::Sqrt(2)))

        $fc = f($c)
        if ([Math]::Abs($fc) -lt 0.0000000001)
        {
            break
        }

        if ($fc -lt 0)
        {
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            $a = $c
        }
        else
        {
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            $b = $c
        }
    }
    return $c
}

function f($x)
{
    return $x * $x - 2
}

$a = 1
$b = 2
Write-Host ([String]::Format("{0,12:F10}", (falseposition $a $b)))
Z:\>powershell -file Z:\0902.ps1
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624     0.0000000000
1.4142135624

Perl

my $a = 1;
my $b = 2;
printf("%12.10f\n", falseposition($a, $b));

sub falseposition
{
    my ($a, $b) = @_;
    my $c;
    while (1)
    {
        # 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        $c = ($a * f($b) - $b * f($a)) / (f($b) - f($a));
        printf("%12.10f\t%13.10f\n", $c, $c - sqrt(2));

        my $fc = f($c);
        if (abs($fc) < 0.0000000001)
        {
            last;
        }

        if ($fc < 0)
        {
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            $a = $c;
        }
        else
        {
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            $b = $c;
        }
    }
    $c;
}

sub f
{
    my ($x) = @_;
    $x * $x - 2;
}
Z:\>perl Z:\0902.pl
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

PHP

<?php
$a = 1;
$b = 2;
printf("%12.10f\n", falseposition($a, $b));

function falseposition($a, $b)
{
    while (TRUE)
    {
        # 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        $c = ($a * f($b) - $b * f($a)) / (f($b) - f($a));
        printf("%12.10f\t%13.10f\n", $c, $c - sqrt(2));

        $fc = f($c);
        if (abs($fc) < 0.0000000001) break;

        if ($fc < 0)
        {
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            $a = $c;
        }
        else
        {
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            $b = $c;
        }
    }
    return $c;
}

function f($x)
{
    return $x * $x - 2;
}
?>
Z:\>php Z:\0902.php
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

Python

# coding: Shift_JIS

import math

def f(x):
    return x * x - 2.0

def falseposition(a, b):
    while True:
        # 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c  = (a * f(b) - b * f(a)) / (f(b) - f(a))
        print "%12.10f\t%13.10f" % (c, c - math.sqrt(2))

        fc = f(c)
        if (abs(fc) < 0.0000000001):
            break

        if (fc < 0):
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c
        else:
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c
    return c

a = 1.0
b = 2.0
print "%12.10f" % falseposition(a, b)
Z:\>python Z:\0902.py
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

Ruby

include Math

def f(x)
    x * x - 2.0
end

def falseposition(a, b)
    while true
        # 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c  = (a * f(b) - b * f(a)) / (f(b) - f(a))
        printf("%12.10f\t%13.10f\n", c, c - sqrt(2))

        fc = f(c)
        if fc.abs < 0.0000000001
            break
        end

        if fc < 0
            # f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c
        else
            # f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c
        end
    end

    c
end

a = 1.0
b = 2.0
printf("%12.10f\n", falseposition(a, b))
Z:\>ruby Z:\0902.rb
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

Groovy

a = 1
b = 2
printf ("%12.10f\n" , falseposition(a, b))

def falseposition(a, b) {
    while (true) {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c  = (a * f(b) - b * f(a)) / (f(b) - f(a))
        printf("%12.10f\t%13.10f\n", c, c - Math.sqrt(2))

        fc = f(c)
        if (Math.abs(fc) < 0.0000000001) break

        if (fc < 0) {
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c
        } else {
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c
        }
    }
    c
}

def f(x) {
    x * x - 2
}
Z:\>groovy Groovy0902.groovy
1.3333333333    -0.0808802291
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

Pascal

program Pas0902(arg);
{$MODE delphi}

uses
    SysUtils, Math;

function f(x:Double):Double;
begin
    result := x * x - 2.0;
end;

function falseposition(a:Double; b:Double):Double;
var
    c:  Double;
    fc: Double;
begin
    while true do
    begin
        { 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点 }
        c := (a * f(b) - b * f(a)) / (f(b) - f(a));
        writeln(format('%12.10f'#9'%13.10f', [c, c - Sqrt(2)]));

        fc := f(c);
        if Abs(fc) < 0.0000000001 then break;

        if fc < 0 then
        begin
            { f(c) < 0 であれば, 解は区間 (c, b) の中に存在 }
            a := c;
        end
        else
        begin
            { f(c) > 0 であれば, 解は区間 (a, c) の中に存在 }
            b := c;
        end;
    end;

    result := c;
end;

var
    a:  Double = 1.0;
    b:  Double = 2.0;
begin
    writeln(format('%12.10f', [falseposition(a, b)]));
end.
Z:\>fpc -v0 -l- Pas0902.pp

Z:\>Pas0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624     0.0000000000
1.4142135624

Ada

with TEXT_IO, Ada.Long_Float_Text_IO, Ada.Numerics.Long_Elementary_Functions;
use  TEXT_IO, Ada.Long_Float_Text_IO, Ada.Numerics.Long_Elementary_Functions;

procedure Ada0902 is

    function f(x:Long_Float) return Long_Float is
    begin
        return x * x - 2.0;
    end f;

    function falseposition(x0:Long_Float; x1:Long_Float) return Long_Float is
        a:  Long_Float;
        b:  Long_Float;
        c:  Long_Float;
        fc: Long_Float;
    begin
        a := x0;
        b := x1;
        while true loop
            -- 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
            c := (a * f(b) - b * f(a)) / (f(b) - f(a));
            Put(c,             Fore=>2, Aft=>10, Exp=>0);
            Put(Ascii.HT);
            Put(c - Sqrt(2.0), Fore=>2, Aft=>10, Exp=>0);
            New_Line;

            fc := f(c);
            if Abs(fc) < 0.0000000001 then
                exit;
            end if;

            if fc < 0.0 then
                -- f(c) < 0 であれば, 解は区間 (c, b) の中に存在
                a := c;
            else
                -- f(c) > 0 であれば, 解は区間 (a, c) の中に存在
                b := c;
            end if;
        end loop;

        return c;
    end falseposition;

    a: Long_Float := 1.0;
    b: Long_Float := 2.0;
begin

    Put(falseposition(a, b), Fore=>2, Aft=>10, Exp=>0);
    New_Line;
end Ada0902;
xxxxxx@yyyyyy /Z
$ gnatmake Ada0902.adb

xxxxxx@yyyyyy /Z
$ Ada0902
 1.3333333333   -0.0808802290
 1.4000000000   -0.0142135624
 1.4117647059   -0.0024488565
 1.4137931034   -0.0004204589
 1.4141414141   -0.0000721482
 1.4142011834   -0.0000123789
 1.4142114385   -0.0000021239
 1.4142131980   -0.0000003644
 1.4142134999   -0.0000000625
 1.4142135516   -0.0000000107
 1.4142135605   -0.0000000018
 1.4142135621   -0.0000000003
 1.4142135623   -0.0000000001
 1.4142135624   -0.0000000000
 1.4142135624

VB.NET

Option Explicit

Module VB0902
    Public Sub Main()
        Dim a As Double = 1.0
        Dim b As Double = 2.0
        Console.WriteLine(String.Format("{0,12:F10}", falseposition(a, b)))
    End Sub

    Private Function falseposition(ByVal a As Double, ByVal b As Double)
        Dim c As Double
        Do While(True)
            '点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
            c = (a * f(b) - b * f(a)) / (f(b) - f(a))
            Console.WriteLine(String.Format("{0,12:F10}{2}{1,13:F10}", c, c - Math.Sqrt(2), vbTab))

            Dim fc As Double = f(c)
            If Math.Abs(fc) < 0.0000000001 Then Exit Do

            If fc < 0 Then
                'f(c) < 0 であれば, 解は区間 (c, b) の中に存在
                a = c
            Else
                'f(c) > 0 であれば, 解は区間 (a, c) の中に存在
                b = c
            End If
        Loop

        Return c
    End Function

    Private Function f(ByVal x As Double) As Double
        Return x * x - 2.0
    End Function
End Module
Z:\>vbc -nologo VB0902.vb

Z:\>VB0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624     0.0000000000
1.4142135624

C#

using System;

public class CS0902
{
    public static void Main()
    {
        double a = 1;
        double b = 2;
        Console.WriteLine(string.Format("{0,12:F10}", falseposition(a, b)));
    }

    private static double falseposition(double a, double b)
    {
        double c;
        while (true)
        {
            // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点 c
            c = (a * f(b) - b * f(a)) / (f(b) - f(a));
            Console.WriteLine(string.Format("{0,12:F10}\t{1,13:F10}", c, c - Math.Sqrt(2)));

            double fc = f(c);
            if (Math.Abs(fc) < 0.0000000001) break;

            if (fc < 0)
            {
                // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
                a = c;
            }
            else
            {
                // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
                b = c;
            }
        }
        return c;
    }

    private static double f(double x)
    {
        return x * x - 2;
    }
}
Z:\>csc -nologo CS0902.cs

Z:\>CS0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624     0.0000000000
1.4142135624

Java

import static java.lang.System.out;

public class Java0902 {

    public static void main(String []args) {
        double a = 1;
        double b = 2;
        out.println(String.format("%12.10f", falseposition(a, b)));
    }

    private static double falseposition(double a, double b) {
        double c;
        while (true) {
            // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
            c = (a * f(b) - b * f(a)) / (f(b) - f(a));
            out.println(String.format("%12.10f\t%13.10f", c, c - Math.sqrt(2)));

            double fc = f(c);
            if (Math.abs(fc) < 0.0000000001) break;

            if (fc < 0){
                // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
                a = c;
            } else {
                // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
                b = c;
            }
        }
        return c;
    }

    private static double f(double x) {
        return x * x - 2;
    }
}
Z:\>javac Java0902.java

Z:\>java Java0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

C++

#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;

double f(double x)
{
    return x * x - 2;
}

double falseposition(double a, double b)
{
    double c;
    while (true)
    {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c = (a * f(b) - b * f(a)) / (f(b) - f(a));
        cout << setw(12) << fixed << setprecision(10) << c << "\t";
        cout << setw(13) << fixed << setprecision(10) << c - sqrt(2) << endl;

        double fc = f(c);
        if (fabs(fc) < 0.0000000001) break;

        if (fc < 0)
        {
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c;
        }
        else
        {
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c;
        }
    }
    return c;
}

int main()
{
    double a = 1;
    double b = 2;
    cout << setw(12) << fixed << setprecision(10) << falseposition(a, b) << endl;
    return 0;
}
Z:\>bcc32 -q CP0902.cpp
cp0902.cpp:

Z:\>CP0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

Objective-C

#import <Foundation/Foundation.h>
#import <math.h>

double f(double x)
{
    return x * x - 2;
}

double falseposition(double a, double b)
{
    double c;
    while (YES)
    {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c = (a * f(b) - b * f(a)) / (f(b) - f(a));
        printf("%12.10f\t%13.10f\n", c, c - sqrt(2));

        double fc = f(c);
        if (fabs(fc) < 0.0000000001) break;

        if (fc < 0)
        {
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c;
        }
        else
        {
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c;
        }
    }
    return c;
}

int main()
{
    double a = 1;
    double b = 2;
    printf("%12.10f\n", falseposition(a, b));
    return 0;
}
xxxxxx@yyyyyy /Z
$ gcc -o OC0902 OC0902.m -lobjc -lgnustep-base -I $INCLUDE -L $LIB $CFLAGS

xxxxxx@yyyyyy /Z
$ OC0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

D

import std.stdio;
import std.math;

void main(string[] args)
{
    double a = 1;
    double b = 2;
    writefln("%12.10f", falseposition(a, b));
}

double falseposition(double a, double b)
{
    double c;
    while (true)
    {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c = (a * f(b) - b * f(a)) / (f(b) - f(a));
        writefln("%12.10f\t%13.10f", c, c - sqrt(2.0));

        double fc = f(c);
        if (fabs(fc) < 0.0000000001) break;

        if (fc < 0)
        {
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c;
        }
        else
        {
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c;
        }
    }
    return c;
}

double f(double x)
{
    return x * x - 2;
}
Z:\>dmd D0902.d

Z:\>D0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135623
1.4117647059    -0.0024488564
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021238
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Go

package main

import "fmt"
import "math"

func main() {
    var a float64 = 1
    var b float64 = 2
    fmt.Printf("%12.10f\n", falseposition(a, b))
}

func falseposition(a float64, b float64) float64 {
    var c float64
    for {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c = (a * f(b) - b * f(a)) / (f(b) - f(a))
        fmt.Printf("%12.10f\t%13.10f\n", c, c - math.Sqrt(2))

        var fc float64 = f(c)
        if math.Fabs(fc) < 0.0000000001 {
            break
        }
        if fc < 0 {
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            a = c
        } else {
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            b = c
        }
    }
    return c
}

func f(x float64) float64 {
    return x * x - 2
}
Z:\>8g GO0902.go

Z:\>8l -o GO0902.exe GO0902.8

Z:\>GO0902
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

Scala

object Scala0902 {

    def main(args: Array[String]) {
        val a = 1.0
        val b = 2.0
        println("%12.10f".format(falseposition(a, b)))
    }

    def falseposition(a:Double, b:Double):Double = {
        // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        val c = (a * f(b) - b * f(a)) / (f(b) - f(a))
        println("%12.10f\t%13.10f".format(c, c - Math.sqrt(2)))

        val fc = f(c)
        if (Math.abs(fc) < 0.0000000001)
            c
        else {
            if (fc < 0) {
                // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
                falseposition(c, b)
            } else {
                // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
                falseposition(a, c)
            }
        }
    }

    def f(x:Double) = {
        x * x - 2
    }
}
Z:\>scala Scala0902.scala
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624

F#

module Fs0902

open System

let f (x:double):double =
    x * x - 2.0

let rec falseposition (a:double) (b:double):double =
    // 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
    let c = (a * f(b) - b * f(a)) / (f(b) - f(a))
    printfn "%12.10f\t%13.10f" c (c - Math.Sqrt(2.0))

    let fc = f c
    if abs(fc) < 0.0000000001 then
        c
    else
        if fc < 0.0 then
            // f(c) < 0 であれば, 解は区間 (c, b) の中に存在
            falseposition c b
        else
            // f(c) > 0 であれば, 解は区間 (a, c) の中に存在
            falseposition a c

let a = 1.0
let b = 2.0
printfn "%12.10f" (falseposition a b)

exit 0
Z:\>fsi  --nologo --quiet Fs0902.fs
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624     0.0000000000
1.4142135624

Clojure

(defn f[x]
    (- (* x x) 2.0))

(defn falseposition [a b]
    ; 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
    (def c (/ (- (* a (f b)) (* b (f a))) (- (f b) (f a))))
    (println (format "%12.10f\t%13.10f" c (- c (Math/sqrt 2))))

    (def fc (f c))
    (if (< (. Math abs fc) 0.00000000001)
        c
        (if (< fc 0)
            (falseposition c b)
            (falseposition a c))))

(def a 1.0)
(def b 2.0)
(println (format "%12.10f" (falseposition a b)))
Z:\>java -cp C:\ProgramFiles\clojure-1.5.1\clojure-1.5.1.jar clojure.main Clj0902.clj
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624    -0.0000000000
1.4142135624    -0.0000000000
1.4142135624

Haskell

import Text.Printf
import Debug.Trace

f::Double->Double
f x = x * x - 2.0

falseposition::Double->Double->Double
falseposition a b =
    let
        -- 点 (a,f(a)) と 点 (b,f(b)) を結ぶ直線と x軸の交点
        c = (a * (f b) - b * (f a)) / ((f b) - (f a))
        fc = (f c) :: Double
    in
        if abs(fc) < 0.0000000001 then
            c
        else
            if fc < 0.0
                then
                    -- f(c) < 0 であれば, 解は区間 (c, b) の中に存在
                    trace (printf "%12.10f\t%13.10f" c (c - ((sqrt 2.0)::Double)))
                    falseposition c b
                else
                    -- f(c) > 0 であれば, 解は区間 (a, c) の中に存在
                    trace (printf "%12.10f\t%13.10f" c (c - ((sqrt 2.0)::Double)))
                    falseposition a c

main = do
    let a = 1.0
    let b = 2.0
    printf "%12.10f\n" (falseposition a b)
Z:\>runghc Hs0902.hs
1.3333333333    -0.0808802290
1.4000000000    -0.0142135624
1.4117647059    -0.0024488565
1.4137931034    -0.0004204589
1.4141414141    -0.0000721482
1.4142011834    -0.0000123789
1.4142114385    -0.0000021239
1.4142131980    -0.0000003644
1.4142134999    -0.0000000625
1.4142135516    -0.0000000107
1.4142135605    -0.0000000018
1.4142135621    -0.0000000003
1.4142135623    -0.0000000001
1.4142135624
inserted by FC2 system