mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Implements part of Complex class in C.
This commit is contained in:
@@ -23,43 +23,43 @@ class Complex < Numeric
|
||||
end
|
||||
|
||||
def +@
|
||||
Complex(real, imaginary)
|
||||
Complex._new(real, imaginary)
|
||||
end
|
||||
|
||||
def -@
|
||||
Complex(-real, -imaginary)
|
||||
Complex._new(-real, -imaginary)
|
||||
end
|
||||
|
||||
def +(rhs)
|
||||
if rhs.is_a? Complex
|
||||
Complex(real + rhs.real, imaginary + rhs.imaginary)
|
||||
Complex._new(real + rhs.real, imaginary + rhs.imaginary)
|
||||
elsif rhs.is_a? Numeric
|
||||
Complex(real + rhs, imaginary)
|
||||
Complex._new(real + rhs, imaginary)
|
||||
end
|
||||
end
|
||||
|
||||
def -(rhs)
|
||||
if rhs.is_a? Complex
|
||||
Complex(real - rhs.real, imaginary - rhs.imaginary)
|
||||
Complex._new(real - rhs.real, imaginary - rhs.imaginary)
|
||||
elsif rhs.is_a? Numeric
|
||||
Complex(real - rhs, imaginary)
|
||||
Complex._new(real - rhs, imaginary)
|
||||
end
|
||||
end
|
||||
|
||||
def *(rhs)
|
||||
if rhs.is_a? Complex
|
||||
Complex(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + rhs.real * imaginary)
|
||||
Complex._new(real * rhs.real - imaginary * rhs.imaginary, real * rhs.imaginary + rhs.real * imaginary)
|
||||
elsif rhs.is_a? Numeric
|
||||
Complex(real * rhs, imaginary * rhs)
|
||||
Complex._new(real * rhs, imaginary * rhs)
|
||||
end
|
||||
end
|
||||
|
||||
def /(rhs)
|
||||
if rhs.is_a? Complex
|
||||
div = rhs.real * rhs.real + rhs.imaginary * rhs.imaginary
|
||||
Complex((real * rhs.real + imaginary * rhs.imaginary) / div, (rhs.real * imaginary - real * rhs.imaginary) / div)
|
||||
Complex._new((real * rhs.real + imaginary * rhs.imaginary) / div, (rhs.real * imaginary - real * rhs.imaginary) / div)
|
||||
elsif rhs.is_a? Numeric
|
||||
Complex(real / rhs, imaginary / rhs)
|
||||
Complex._new(real / rhs, imaginary / rhs)
|
||||
end
|
||||
end
|
||||
alias_method :quo, :/
|
||||
@@ -92,14 +92,6 @@ class Complex < Numeric
|
||||
end
|
||||
alias_method :conj, :conjugate
|
||||
|
||||
def numerator
|
||||
self
|
||||
end
|
||||
|
||||
def denominator
|
||||
1
|
||||
end
|
||||
|
||||
def fdiv(numeric)
|
||||
Complex(real.to_f / numeric, imaginary.to_f / numeric)
|
||||
end
|
||||
@@ -117,36 +109,14 @@ class Complex < Numeric
|
||||
end
|
||||
alias_method :rect, :rectangular
|
||||
|
||||
def to_c
|
||||
self
|
||||
end
|
||||
|
||||
def to_f
|
||||
raise RangeError.new "can't convert #{to_s} into Float" unless imaginary.zero?
|
||||
real.to_f
|
||||
end
|
||||
|
||||
def to_i
|
||||
raise RangeError.new "can't convert #{to_s} into Integer" unless imaginary.zero?
|
||||
real.to_i
|
||||
end
|
||||
|
||||
def to_r
|
||||
raise RangeError.new "can't convert #{to_s} into Rational" unless imaginary.zero?
|
||||
Rational(real, 1)
|
||||
end
|
||||
|
||||
attr_reader :real, :imaginary
|
||||
alias_method :imag, :imaginary
|
||||
end
|
||||
|
||||
class << Complex
|
||||
alias_method :_new, :new
|
||||
undef_method :new
|
||||
|
||||
alias_method :rect, :rectangular
|
||||
end
|
||||
|
||||
module Kernel
|
||||
def Complex(real, imaginary = 0)
|
||||
Complex.rectangular(real, imaginary)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#include <mruby.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/numeric.h>
|
||||
|
||||
struct mrb_complex {
|
||||
mrb_float real;
|
||||
mrb_float imaginary;
|
||||
};
|
||||
|
||||
#include <mruby/data.h>
|
||||
|
||||
static const struct mrb_data_type mrb_complex_type = {"Complex", mrb_free};
|
||||
|
||||
static mrb_value
|
||||
complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary)
|
||||
{
|
||||
struct RClass *c = mrb_class_get(mrb, "Complex");
|
||||
struct mrb_complex *p;
|
||||
|
||||
p = (struct mrb_complex*)mrb_malloc(mrb, sizeof(struct mrb_complex));
|
||||
p->real = real;
|
||||
p->imaginary = imaginary;
|
||||
|
||||
return mrb_obj_value(Data_Wrap_Struct(mrb, c, &mrb_complex_type, p));
|
||||
}
|
||||
|
||||
static struct mrb_complex*
|
||||
complex_ptr(mrb_state *mrb, mrb_value v)
|
||||
{
|
||||
struct mrb_complex *p;
|
||||
|
||||
p = DATA_GET_PTR(mrb, v, &mrb_complex_type, struct mrb_complex);
|
||||
if (!p) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized complex");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_real(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_complex *p = complex_ptr(mrb, self);
|
||||
return mrb_float_value(mrb, p->real);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_imaginary(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_complex *p = complex_ptr(mrb, self);
|
||||
return mrb_float_value(mrb, p->imaginary);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_s_new(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_float real, imaginary;
|
||||
|
||||
mrb_get_args(mrb, "ff", &real, &imaginary);
|
||||
return complex_new(mrb, real, imaginary);
|
||||
}
|
||||
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
static mrb_value
|
||||
complex_to_f(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_complex *p = complex_ptr(mrb, self);
|
||||
|
||||
if (p->imaginary != 0) {
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self);
|
||||
}
|
||||
|
||||
return mrb_float_value(mrb, p->real);
|
||||
}
|
||||
#endif
|
||||
|
||||
static mrb_value
|
||||
complex_to_i(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
struct mrb_complex *p = complex_ptr(mrb, self);
|
||||
|
||||
if (p->imaginary != 0) {
|
||||
mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self);
|
||||
}
|
||||
return mrb_int_value(mrb, p->real);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
complex_to_c(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
void mrb_mruby_complex_gem_init(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *comp;
|
||||
|
||||
#ifdef COMPLEX_USE_ISTRUCT
|
||||
mrb_assert(sizeof(struct mrb_complex) < ISTRUCT_DATA_SIZE);
|
||||
#endif
|
||||
comp = mrb_define_class(mrb, "Complex", mrb_class_get(mrb, "Numeric"));
|
||||
//MRB_SET_INSTANCE_TT(comp, MRB_TT_ISTRUCT);
|
||||
mrb_undef_class_method(mrb, comp, "new");
|
||||
mrb_define_class_method(mrb, comp, "_new", complex_s_new, MRB_ARGS_REQ(2));
|
||||
mrb_define_method(mrb, comp, "real", complex_real, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, comp, "imaginary", complex_imaginary, MRB_ARGS_NONE());
|
||||
#ifndef MRB_WITHOUT_FLOAT
|
||||
mrb_define_method(mrb, comp, "to_f", complex_to_f, MRB_ARGS_NONE());
|
||||
#endif
|
||||
mrb_define_method(mrb, comp, "to_i", complex_to_i, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, comp, "to_c", complex_to_c, MRB_ARGS_NONE());
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_complex_gem_final(mrb_state* mrb)
|
||||
{
|
||||
}
|
||||
@@ -37,7 +37,7 @@ rational_new(mrb_state *mrb, mrb_int numerator, mrb_int denominator)
|
||||
struct mrb_rational *p = rational_ptr(rat);
|
||||
p->numerator = numerator;
|
||||
p->denominator = denominator;
|
||||
return mrb_obj_value(s);
|
||||
return rat;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
|
||||
Reference in New Issue
Block a user