最も0に近い数字を求める

30分プログラム、その599。 限りなく小さくするという記事を参考に、最も0に近い数字を求めてみる。

元々はFortranのコードらしいですが、ボクはFortranは読めないのでPython版を参考にさせてもらいます。

eps = 1.0
while eps+1.0 > 1.0: eps = eps/2.0
# eps=1.1102230246251565e-16

1+x==1を満すまて、2で割り続けることで求めれるらしいです。

最初は素直にwhileで書き始めたんですが、途中でニュートン法っぽく書けることに気がついたので、そう書き直しました。あとついでに、正・負両方について求めてみました。

使い方

$ perl min.pl
1.11022302462516e-16
-5.55111512312578e-17

ソースコード

#! /usr/bin/perl
# -*- mode:perl; coding:utf-8 -*-
#
# min.pl -
#
# Copyright(C) 2009 by mzp
# Author: MIZUNO Hiroki / mzpppp at gmail dot com
# http://howdyworld.org
#
# Timestamp: 2009/06/06 21:45:43
#
# This program is free software; you can redistribute it and/or
# modify it under MIT Lincence.
#
use strict;
use warnings;
use Data::Dumper;


sub newton($$$) {
    my ($improve,$is_good,$x) = @_;
    my $y = $improve->($x);

    if ($is_good->($x,$y)) {
	$y;
    } else {
	&newton($improve,$is_good,$y);
    }
}

my $pos =  newton(sub{ $_[0] / 2.0 },
		  sub{ $_[1] + 1.0 == 1.0 },
		  1.0);
print $pos,"\n";


my $neg =  newton(sub{ $_[0] / 2.0 },
		  sub{ $_[1] + 1.0 == 1.0 },
		  -1.0);
print $neg,"\n";