[#20525] [BigDecimal] changing rule of coerce — "Tadashi Saito" <shiba@...2.accsnet.ne.jp>

斎藤です。

44 messages 2003/07/07
[#20527] Re: [BigDecimal] changing rule of coerce — "Shigeo Kobayashi" <shigeo@...> 2003/07/07

小林です。

[#20528] Re: [BigDecimal] changing rule of coerce — matz@... (Yukihiro Matsumoto) 2003/07/07

まつもと ゆきひろです

[#20570] Marshal upgrade — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

41 messages 2003/07/09
[#20575] Re: Marshal upgrade — Masatoshi SEKI <m_seki@...> 2003/07/09

咳といいます。

[#20583] Re: Marshal upgrade — matz@... (Yukihiro Matsumoto) 2003/07/09

まつもと ゆきひろです

[#21016] Re: Marshal upgrade — matz@... (Yukihiro Matsumoto) 2003/07/30

まつもと ゆきひろです

[#20804] add library — nobu.nakada@... 2003/07/23

なかだです。

[#20580] add library(Re:ruby-dev:20570) — たむらけんいち <sgs02516@...>

たむらです。

30 messages 2003/07/09
[#20656] Re: add library — "NAKAMURA, Hiroshi" <nakahiro@...> 2003/07/14

なひです。

[#20658] Re: add library — GOTOU Yuuzou <gotoyuzo@...> 2003/07/14

In message <038d01c349cb$eaad71d0$93222fc0@sarion.co.jp>,

[#20659] Re: add library — matz@... (Yukihiro Matsumoto) 2003/07/14

まつもと ゆきひろです

[#20660] Re: add library — GOTOU Yuuzou <gotoyuzo@...> 2003/07/14

In message <1058171960.400840.10041.nullmailer@picachu.netlab.jp>,

[#20661] Re: add library — Takahiro Kambe <taca@...> 2003/07/14

話をそらしてしまうかもしれませんが、

[#20665] Re: add library — GOTOU Yuuzou <gotoyuzo@...> 2003/07/14

In message <20030714.183104.09092354.taca@back-street.net>,

[#20666] Re: add library — Takahiro Kambe <taca@...> 2003/07/14

In message <20030715.013655.424936247.gotoyuzo@kotetsu.does.notwork.org>

[#20668] Re: add library — GOTOU Yuuzou <gotoyuzo@...> 2003/07/14

In message <20030715.025907.26217115.taca@back-street.net>,

[#20750] Re: add library — Takahiro Kambe <taca@...> 2003/07/21

In message <20030715.051853.968499478.gotoyuzo@kotetsu.does.notwork.org>

[#20751] Re: add library — GOTOU Yuuzou <gotoyuzo@...> 2003/07/21

In message <20030721.163444.09092937.taca@back-street.net>,

[#20655] frozen ThreadGroup — Hidetoshi NAGAI <nagai@...>

永井@知能.九工大です.

26 messages 2003/07/14
[#20671] Re: frozen ThreadGroup — matz@... (Yukihiro Matsumoto) 2003/07/14

まつもと ゆきひろです

[#20673] Re: frozen ThreadGroup — Hidetoshi NAGAI <nagai@...> 2003/07/15

永井@知能.九工大です.

[#20676] Re: frozen ThreadGroup — matz@... (Yukihiro Matsumoto) 2003/07/15

まつもと ゆきひろです

[#20677] Re: frozen ThreadGroup — Hidetoshi NAGAI <nagai@...> 2003/07/15

永井@知能.九工大です.

[#20681] Re: frozen ThreadGroup — matz@... (Yukihiro Matsumoto) 2003/07/15

まつもと ゆきひろです

[#20690] portable(?) UserID/GroupID control (Re: frozen ThreadGroup) — Hidetoshi NAGAI <nagai@...> 2003/07/16

永井@知能.九工大です.

[#20712] Re: portable(?) UserID/GroupID control — Hidetoshi NAGAI <nagai@...> 2003/07/17

永井@知能.九工大です.

[#20735] Re: portable(?) UserID/GroupID control — matz@... (Yukihiro Matsumoto) 2003/07/20

まつもと ゆきひろです

[#20736] Re: portable(?) UserID/GroupID control — Hidetoshi NAGAI <nagai@...> 2003/07/20

永井@知能.九工大です.

[#20737] Re: portable(?) UserID/GroupID control — matz@... (Yukihiro Matsumoto) 2003/07/20

まつもと ゆきひろです

[#20748] [BigDecimal] exception handling — "Tadashi Saito" <shiba@...2.accsnet.ne.jp>

斎藤です。

20 messages 2003/07/21

[#20765] Re: [ruby-cvs] ruby/lib: * lib/tmpdir.rb: new library to get temporary directory path, — WATANABE Hirofumi <eban@...>

わたなべです。

9 messages 2003/07/21

[#20780] complex.rb — Masahiro TANAKA <masa@...>

complex.rb についての修正案を[ruby-math:00543]で提案しましたが、その後

25 messages 2003/07/22
[#20782] Re: complex.rb — matz@... (Yukihiro Matsumoto) 2003/07/22

まつもと ゆきひろです

[#20900] Re: complex.rb — Masahiro TANAKA <masa@...> 2003/07/25

At Tue, 22 Jul 2003 17:30:31 +0900, Yukihiro Matsumoto wrote:

[#20905] Re: complex.rb — matz@... (Yukihiro Matsumoto) 2003/07/25

まつもと ゆきひろです

[#20906] Re: complex.rb — keiju@... (石塚圭樹) 2003/07/25

けいじゅ@いしつかです.

[#20810] Rational 始めました。 — Shin-ichiro HARA <sinara@...>

原です。

13 messages 2003/07/23
[#20876] Re: Rational 始めました。 — keiju@... (石塚圭樹) 2003/07/24

けいじゅ@いしつかです.

[#20954] ruby 1.8.0 preview5 — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

15 messages 2003/07/28

[#20957] [BigDecimal] conflict between Numeric#div and BigDecimal#div — "Tadashi Saito" <shiba@...2.accsnet.ne.jp>

斎藤です。

29 messages 2003/07/28
[#20960] Re: [BigDecimal] conflict between Numeric#div and BigDecimal#div — Masahiro TANAKA <masa@...> 2003/07/28

At Mon, 28 Jul 2003 18:26:20 +0900, Tadashi Saito wrote:

[#20962] Re: [BigDecimal] conflict between Numeric#div and BigDecimal#div — matz@... (Yukihiro Matsumoto) 2003/07/28

まつもと ゆきひろです

[#20990] Re: [BigDecimal] conflict between Numeric#div and BigDecimal#div — Masahiro TANAKA <masa@...> 2003/07/29

At Mon, 28 Jul 2003 21:16:08 +0900, Yukihiro Matsumoto wrote:

[#20992] Re: [BigDecimal] conflict between Numeric#div and BigDecimal#div — matz@... (Yukihiro Matsumoto) 2003/07/29

まつもと ゆきひろです

[ruby-dev:20552] Re: [BigDecimal] renaming proposal

From: "Tadashi Saito" <shiba@...2.accsnet.ne.jp>
Date: 2003-07-08 08:47:10 UTC
List: ruby-dev #20552
斎藤です。なにか誤解していたみたいです。

----- Original Message ----- 
From: "Shigeo Kobayashi" <shigeo@tinyforest.gr.jp>
Sent: Tuesday, July 08, 2003 4:59 PM
Subject: [ruby-dev:20550] Re: [BigDecimal] renaming proposal


> > 「現状のbigdecimal.cの数学関数の部分は削除して、Rubyで
> >  書き直し、それを標準添付の一部としたい」
> >
> > ということだと思ったのですが、そうではない、ということでしょうか。
> いや、そういうことを意味したかったんですが...
>
> > 数学関数を標準添付したくないということですか?
> 標準添付できたらいいなと思っています。

了解です。自分が誤解していたらしく、すみませんでした。

とりあえず今まで作った分を、添付してみました。
[ruby-dev:20547]で添付したテストも、少なくともN=700くらいまでは
OKになることを確認済みです。

ただ自分は小林さんと違い、あまり数学に造詣が深くありません。
むしろ苦手だった方です。
今回のスクリプトも、奥村先生のアルゴリズム辞典や
数学の本を片手にほぼそのまま、コピーしただけです。
ですので、いろいろと修正して下さればありがたいです。
(自分も安直にテーラー展開(正確にはマクローリン展開?)した
だけなので…)

> 要するにBigDecimal::E(n)等が、正確に n 桁を保証できてい
> ないということだと思います。(計算内部の)中間変数の精度
> をもう少し上げればましになるとは思いますが、x**n/(n!) のよう
> な計算を繰り返し実行する単純なテーラー展開では所詮こん
> なものかもしれませんね。 やはり、削除したくなってきた!

いやいや、落ち着いてください ^^;;

自分も、正確な n 桁を保証するという方法のが分かりませんでした。
そこでとりあえず、ループ中の足し算の中で
「もし以前の結果と足した後の結果の n 桁が等しければ
 ループを抜ける」
という方法を取りました。が、数学的にはとてもあやしいと思います。

> > 手元で作ったスクリプトはもちろんそうしてありますが、
> > BigDecimal自体について言っているつもりでした。
> もちろん、 bigdecimal.c 内でより良いものがサポートできれば
> 申し分ないです。ただ、現状の関数は我ながらお粗末なので、
> できれば bigdecimal.c から E や sincos 等を削除したいと思っ
> ているわけです。

いやいや、そこまでおっしゃるほど悪いものではないと思いますよ。

添付したものは結構冗長なものになってしまいました。
EとPIはまだ実装していません。
とりあえずのたたき台バージョンということで。
おまけに、BigDecimal#to_fを再定義しています。
この話題は、また別のスレッドで。

---
斎藤ただし

Attachments (1)

bigdecimal-math.rb (4.25 KB, text/x-ruby)
require 'bigdecimal'

class BigDecimal
  def to_f
    f, x, y, z = self.split
    s = '0.' + x
    f * s.to_f * y ** z
  end
end

module Math
  alias sqrt! sqrt
  alias log! log
  alias sin! sin
  alias cos! cos
  alias exp! exp

  def sqrt(x, n = nil)
    maxnr = 100

    unless x.class == BigDecimal
      raise ArgumentError, 'wrong number of arguments(2 for 1)' unless n.nil?
      return sqrt!(x)
    end

    raise ArgumentError, "argument out of domain" if x < 0
    return x if x.zero? || x.infinite? || x.nan?
    
    if n.nil?
      n = [x.prec[0], x.exponent].max
    elsif n <= 0
      raise ArgumentError, "zero or negative argument"
    end
    
    two = BigDecimal.new('2')
    unless x > Float::MAX
      f = sqrt!(x.to_f)
      s = BigDecimal.new(f.to_s)
    else
      one = BigDecimal.new('1')
      s = (x > one) ? x : one
    end
    exp = s.exponent

    t = nil
    maxnr.times do
      last = s
      s = (x/s + s) / two
      t = s.truncate(n-exp)
      break if s == last || (s.prec[0] >= n && t == last.truncate(n-exp))
    end
    t
  end

  def log(x, n = nil)
    maxnr = 100

    unless x.class == BigDecimal
      raise ArgumentError, 'wrong number of arguments(2 for 1)' unless n.nil?
      return log!(x)
    end

    raise ArgumentError, "argument out of domain" if x <= 0
    return x if x.infinite? || x.nan?
    
    if n.nil?
      n = [x.prec[0], x.exponent].max
    elsif n <= 0
      raise ArgumentError, "zero or negative argument"
    end
    
    u = (x - 1) / (x + 1)
    u2 = u * u
    s = 2 * u
    exp = s.exponent

    t = nil
    i = 1
    maxnr.times do
      last = s
      u *= u2
      i += 2
      s += 2 * u / i
      t = s.truncate(n-exp)
      break if s == last || (s.prec[0] >= n && t == last.truncate(n-exp))
    end
    t
  end

  def sin(x, n = nil)
    maxnr = 100

    unless x.class == BigDecimal
      raise ArgumentError, 'wrong number of arguments(2 for 1)' unless n.nil?
      return sin!(x)
    end
    
    zero = BigDecimal.new('0')
    nan = zero / zero
    return nan if x.infinite? || x.nan?
    
    if n.nil?
      n = [x.prec[0], x.exponent].max
    elsif n <= 0
      raise ArgumentError, "zero or negative argument"
    end
    
    one = BigDecimal.new('1')
    two = BigDecimal.new('2')
    x1 = x
    x2 = x * x
    sign = one
    y = x
    m = one
    d = one

    z = nil
    maxnr.times do
      last = y
      sign = -sign
      x1 *= x2
      m += two
      d *= (m-one) * m
      y += sign * x1 / d
      z = y.truncate(n)
      break if y == last || (y.prec[0] >= n && z == last.truncate(n))
    end
    z
  end

  def cos(x, n = nil)
    maxnr = 100

    unless x.class == BigDecimal
      raise ArgumentError, 'wrong number of arguments(2 for 1)' unless n.nil?
      return cos!(x)
    end
    
    zero = BigDecimal.new('0')
    nan = zero / zero
    return nan if x.infinite? || x.nan?
    
    if n.nil?
      n = [x.prec[0], x.exponent].max
    elsif n <= 0
      raise ArgumentError, "zero or negative argument"
    end
    
    one = BigDecimal.new('1')
    two = BigDecimal.new('2')
    x1 = one
    x2 = x * x
    sign = one
    y = one
    m = zero
    d = one

    z = nil
    maxnr.times do
      last = y
      sign = -sign
      x1 *= x2
      m += two
      d *= (m-one) * m
      y += sign * x1 / d
      z = y.truncate(n)
      break if y == last || (y.prec[0] >= n && z == last.truncate(n))
    end
    z
  end

  def exp(x, n = nil)
    maxnr = 100

    unless x.class == BigDecimal
      raise ArgumentError, 'wrong number of arguments(2 for 1)' unless n.nil?
      return exp!(x)
    end
    
    zero = BigDecimal.new('0')
    return zero if x.infinite? == -1
    return x if x.nan? || x.infinite?
    
    if n.nil?
      n = [x.prec[0], x.exponent].max
    elsif n <= 0
      raise ArgumentError, "zero or negative argument"
    end
    
    one = BigDecimal.new('1')
    x1 = one
    y = one
    d = one
    m = zero

    z = nil
    maxnr.times do
      last = y
      x1 *= x
      m += one
      d *= m
      y += x1 / d
      z = y.truncate(n)
      break if y == last || (y.prec[0] >= n && z == last.truncate(n))
    end
    z
  end

  module_function :sqrt, :sqrt!
  module_function :log, :log!
  module_function :sin, :sin!
  module_function :cos, :cos!
  module_function :exp, :exp!

end

#sqrt(BigDecimal.new(ARGV[0]))

In This Thread