[#36686] 1.1 < 61.1 - 60.0 — Shin-ichiro HARA <sinara@...>

原です。

19 messages 2002/12/06

[#36770] www.ruby-lang.orgリニューアル準備のお知らせ — TADA Tadashi <sho@...>

ruby-lang.orgのwebmasterチームでは、タイムリーな情報提供と使いやすい

11 messages 2002/12/16

[ruby-list:36716] Re: 1.1 < 61.1 - 60.0

From: Kazuhiro Yoshida <moriq.kazuhiro@...>
Date: 2002-12-09 00:40:05 UTC
List: ruby-list #36716
もりきゅうです。

Shin-ichiro HARA <sinara@blade.nagaokaut.ac.jp> wrote:
> 固定小数点数って具体的にはどうするのですか?そういうクラスを作る
> のですよね。標準でほしいなあ。

こんなのかなと想像してみました。
とりあえず足し算と引き算だけ…。

Fixnum は小数点が右端にある固定小数点数クラスと考えられる。
そこで、数値を @n, 小数点の位置を @d とするクラスを考えて
みました。でも、これだと小数点は動いてるな。全然違うのか。

未対応:
* *, /, %, 精度
* coerce
* 無限, 非数, 0
だめだめ。やっぱり BigFloat を使うのが吉か。

class Fix
  attr_reader :n, :d
  def initialize(n=0, d=0)
    @n = n
    @d = d
    norm
  end
  def Fix.new_str(str)
    if str.index('.')
      Fix.new str.delete('.').to_i, -(str.size - str.index('.') - 1)
    else
      Fix.new str.to_i, 0
    end
  end
  def to_s
    str = @n.to_s
    if @d < 0
      if str.size > -@d
        str[str.size-(-@d),0] = '.'
      else
        str[0,0] = '0.' << '0'*(-@d-1)
      end
    else
      str << '0'*@d
    end
    str
  end
  def value=(v)
    @n = v
    norm
  end
  def value
    @n * 10 ** @d
  end
  alias to_f value
  def to_i
    @d < 0 ? 0 : @n
  end
  def +(other)
    case other
    when Fix
      x = other
    when Fixnum
      x = Fix.new other, 0
    else
      raise TypeError
    end
    case @d <=> x.d
    when +1
      Fix.new @n * 10 ** (@d - x.d) + x.n, x.d
    when -1
      Fix.new @n + x.n * 10 ** (x.d - @d), @d
    else
      Fix.new @n + x.n, @d
    end
  end
  def +@
    Fix.new(+@n, @d)
  end
  def -@
    Fix.new(-@n, @d)
  end
  def -(other)
    self + -other
  end
  def <=>(other)
    case @d <=> other.d
    when +1
      @n * 10 ** (@d - other.d) <=> other.n
    when -1
      @n <=> other.n * 10 ** (other.d - @d)
    else
      @n <=> other.n
    end
  end
  def check
    raise TypeError unless @n.is_a? Fixnum
    raise TypeError unless @d.is_a? Fixnum
  end
  def norm
    check
    while @n%10 == 0
      @n /= 10
      @d += 1
    end
  end
end

a = Fix.new 1,0
p a
puts a
b = Fix.new 2,3
p b
puts b
c = Fix.new 2001
p c
puts c

p a+b
p b+a

p a<=>b
p b<=>a
p a<=>c
p c<=>a
p b<=>c
p c<=>b
p c<=>a+b
p a+b<=>c

p Fix.new 611,-1
p Fix.new 600,-1
x = Fix.new_str "61.1"
p x
p +x
p -x
y = Fix.new_str "60.0"
p y
z=x-y
p z
puts z
w=z-1
p w
puts w
q = Fix.new_str "-1"
p q
puts q

----
YOSHIDA Kazuhiro  moriq@moriq.com  http://www.moriq.com/

In This Thread

Prev Next