lib/hpsqrt.rb in hpsqrt-1.1.0 vs lib/hpsqrt.rb in hpsqrt-1.2.0
- old
+ new
@@ -1,7 +1,7 @@
require 'hpsqrt/inspect_mode'
-require 'hpsqrt/value'
+require 'hpsqrt/term'
require 'hpsqrt/version'
class HpSqrt < Numeric
@@ -14,77 +14,77 @@
def self.inspect_mode=(v)
@@inspect_mode = v
end
- attr_reader :values
+ attr_reader :terms
- def initialize(values)
- @values = values.freeze
+ def initialize(terms)
+ @terms = terms.freeze
freeze
end
def -@
- values = self.values.map{|v,c| [v, -c]}.to_h
- self.class.new(values)
+ terms = @terms.map{|t,c| [t, -c]}.to_h
+ self.class.new(terms)
end
def +(other)
other = self.class.create(other)
- values = @values.merge(other.values) {|v, c1, c2|
+ terms = @terms.merge(other.terms) {|t, c1, c2|
c1 + c2
}
- values.delete_if {|v,c| c==0}
+ terms.delete_if {|t,c| c==0}
- self.class.new(values)
+ self.class.new(terms)
end
def -(other)
other = self.class.create(other)
- other_values = other.values.map{|v,c| [v, -c]}.to_h
- values = @values.merge(other_values) {|v, c1, c2|
+ other_terms = other.terms.map{|t,c| [t, -c]}.to_h
+ terms = @terms.merge(other_terms) {|t, c1, c2|
c1 + c2
}
- values.delete_if {|v,c| v==0}
+ terms.delete_if {|t,c| c==0}
- self.class.new(values)
+ self.class.new(terms)
end
def *(other)
other = self.class.create(other)
- values = {}
- @values.each {|v1, c1|
- other.values.each {|v2, c2|
- v = v1 * v2
+ terms = {}
+ @terms.each {|t1, c1|
+ other.terms.each {|t2, c2|
+ t = t1 * t2
c = c1 * c2
- values[v] ||= 0
- values[v] += c
+ terms[t] ||= 0
+ terms[t] += c
}
}
- values.delete_if {|v,c| c==0}
+ terms.delete_if {|t,c| c==0}
- self.class.new(values)
+ self.class.new(terms)
end
def /(other)
other = self.class.create(other)
- other_inv = Value.new(number: Rational(1, other.value))
+ other_inv = Term.new(number: Rational(1, other.to_c))
- values = {}
- @values.each {|v, c|
- v *= other_inv
+ terms = {}
+ @terms.each {|t, c|
+ t *= other_inv
- values[v] ||= 0
- values[v] += c
+ terms[t] ||= 0
+ terms[t] += c
}
- values.delete_if {|v,c| c==0}
+ terms.delete_if {|t,c| c==0}
- self.class.new(values)
+ self.class.new(terms)
end
def **(other)
other = self.class.create(other)
@@ -97,40 +97,40 @@
if other_i<0
result = Rational(1, result)
end
result
else
- self.class.number(self.value ** other.value)
+ self.class.number(self.to_c ** other.to_c)
end
end
def coerce(other)
[self.class.create(other), self]
end
def ==(other)
if self.class==other
- self.value==other.value
+ self.to_c==other.to_c
elsif Numeric===other
- self.value==other
+ self.to_c==other
else
super.==(other)
end
end
- def value
- @values.map {|v, c|
- v.number * Math.sqrt(Complex(v.sqrt)) * c
- }.sum
+ def to_c
+ @terms.map {|t, c|
+ t.number * Math.sqrt(Complex(t.sqrt)) * c
+ }.sum.to_c
end
def real
- value.real
+ to_c.real
end
def imag
- Complex(value).imag
+ to_c.imag
end
def to_i
c = to_c
if c.imag.zero?
@@ -147,35 +147,37 @@
else
raise RangeError, "can't convert %s into Float" % c
end
end
- def to_c
- value.to_c
- end
-
def to_r
- value.to_r
+ c = to_c
+ if c.imag.zero?
+ Rational(c.real, 1)
+ else
+ raise RangeError, "can't convert %s into Rational" % c
+ end
end
def expr
value_to_s = -> (v) {
if Complex===v && v.imag.zero?
v = v.real
- elsif Rational===v
+ end
+ if Rational===v
v = v.to_s.sub(/\/1$/, "")
end
v = v.to_s
if v !~ /^[\d\.]+$/
v = "(%s)" % v
end
v
}
- result = @values.map {|v, c|
- n = v.number * c
- s = v.sqrt
+ result = @terms.map {|t, c|
+ n = t.number * c
+ s = t.sqrt
if s!=1
if n==1
"\u221A%s" % value_to_s[s]
elsif 0<n.real
@@ -202,15 +204,15 @@
end
def to_s
case @@inspect_mode
when INSPECT_MODE::VALUE
- value.to_s
+ to_c.to_s
when INSPECT_MODE::EXPR
expr
else
- "#<%s:0x%016x value=(%s) expr=(%s)>" % [self.class.name, self.object_id, value, expr]
+ "#<%s:0x%016x value=(%s) expr=(%s)>" % [self.class.name, self.object_id, to_c, expr]
end
end
def real?
imag.zero?
@@ -219,19 +221,17 @@
def imag?
!real?
end
def int?
- v = value
- is_imag = Complex===v && !v.imag.zero?
- !is_imag && v.real==v.real.to_i
+ c = to_c
+ c.imag.zero? && c.real==c.real.to_i
end
def float?
- v = value
- is_imag = Complex===v && !v.imag.zero?
- !is_imag && Float===v.real && v.real!=v.real.to_i
+ c = to_c
+ c.imag.zero? && Float===c.real && c.real!=c.real.to_i
end
def self.create(v)
if self===v
v
@@ -239,12 +239,27 @@
number(v)
end
end
def self.number(v)
- new({Value.new(number: v) => 1})
+ if v!=0
+ new({Term.new(number: v) => 1})
+ else
+ zero
+ end
end
def self.sqrt(v)
- new({Value.new(sqrt: v) => 1})
+ if self===v
+ v = v.to_c
+ end
+ if v!=0
+ new({Term.new(sqrt: v) => 1})
+ else
+ zero
+ end
+ end
+
+ def self.zero
+ new({})
end
end