Skip to content

Commit

Permalink
Update rational arithmetic operations
Browse files Browse the repository at this point in the history
Signed-off-by: yamacir-kit <[email protected]>
  • Loading branch information
yamacir-kit committed Aug 15, 2022
1 parent 5df86a2 commit ad67f24
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 59 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ sudo rm -rf /usr/local/share/meevax

| Target Name | Description
|:-------------------|:--
| `all` (default) | Build shared-library `libmeevax.0.4.206.so` and executable `meevax`.
| `all` (default) | Build shared-library `libmeevax.0.4.207.so` and executable `meevax`.
| `test` | Test executable `meevax`.
| `package` | Generate debian package `meevax_0.4.206_amd64.deb`.
| `package` | Generate debian package `meevax_0.4.207_amd64.deb`.
| `install` | Copy files into `/usr/local` __(1)__.
| `install.deb` | `all` + `package` + `sudo apt install <meevax>.deb`
| `safe-install.deb` | `all` + `test` + `package` + `sudo apt install <meevax>.deb`
Expand All @@ -122,7 +122,7 @@ __(1)__ Meevax installed by `make install` cannot be uninstalled by the system's
## Usage

```
Meevax Lisp System, version 0.4.206
Meevax Lisp System, version 0.4.207
Usage: meevax [OPTION...] [FILE...]
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.206
0.4.207
6 changes: 3 additions & 3 deletions include/meevax/kernel/ratio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ inline namespace kernel

ratio(ratio &&);

explicit ratio(const_reference, const_reference);
explicit ratio(exact_integer const&);

explicit ratio(exact_integer const&, exact_integer const&);

explicit ratio(double);

Expand All @@ -45,8 +47,6 @@ inline namespace kernel

auto denominator() const -> value_type;

auto invert() const -> ratio;

auto numerator() const -> value_type;

explicit operator double() const;
Expand Down
10 changes: 5 additions & 5 deletions src/kernel/exact_integer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ inline namespace kernel
mpz_init_set(value, z);
}

exact_integer::exact_integer(exact_integer const& given) noexcept
exact_integer::exact_integer(exact_integer const& other) noexcept
{
mpz_init_set(value, given.value);
mpz_init_set(value, other.value);
}

exact_integer::exact_integer(exact_integer && rhs) noexcept
exact_integer::exact_integer(exact_integer && other) noexcept
{
*value = *rhs.value;
mpz_init(rhs.value);
mpz_init(value);
mpz_swap(value, other.value);
}

exact_integer::exact_integer(int rhs)
Expand Down
74 changes: 37 additions & 37 deletions src/kernel/number.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@ inline namespace kernel
auto operator + (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_add(n.value, a.value, b.value); return n; }
auto operator - (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_sub(n.value, a.value, b.value); return n; }
auto operator * (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_mul(n.value, a.value, b.value); return n; }
auto operator / (exact_integer const& a, exact_integer const& b) -> ratio { return ratio(make(a), make(b)); }
auto operator / (exact_integer const& a, exact_integer const& b) -> ratio { return ratio(a, b); }
auto operator % (exact_integer const& a, exact_integer const& b) -> exact_integer { exact_integer n; mpz_tdiv_r(n.value, a.value, b.value); return n; }
auto operator ==(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) == 0; }
auto operator !=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) != 0; }
auto operator < (exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) < 0; }
auto operator <=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) <= 0; }
auto operator ==(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) == 0; }
auto operator > (exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) > 0; }
auto operator >=(exact_integer const& a, exact_integer const& b) -> bool { return mpz_cmp(a.value, b.value) >= 0; }

auto operator * (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.numerator().as<exact_integer>()), b.denominator()); }
auto operator + (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as<exact_integer>() + b.numerator().as<exact_integer>()), b.denominator()); }
auto operator - (exact_integer const& a, ratio const& b) -> ratio { return ratio(make(a * b.denominator().as<exact_integer>() - b.numerator().as<exact_integer>()), b.denominator()); }
auto operator / (exact_integer const& a, ratio const& b) -> ratio { return a * b.invert(); }
auto operator + (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_add(q.value, ratio(a).value, b.value); return q; }
auto operator - (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_sub(q.value, ratio(a).value, b.value); return q; }
auto operator * (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_mul(q.value, ratio(a).value, b.value); return q; }
auto operator / (exact_integer const& a, ratio const& b) -> ratio { ratio q; mpq_div(q.value, ratio(a).value, b.value); return q; }
auto operator % (exact_integer const& , ratio const& ) -> ratio { throw error(make<string>("unsupported operation"), unit); }
auto operator !=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a != x.numerator().as<exact_integer>(); }
auto operator < (exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a < x.numerator().as<exact_integer>(); }
auto operator <=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a <= x.numerator().as<exact_integer>(); }
auto operator ==(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a == x.numerator().as<exact_integer>(); }
auto operator > (exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a > x.numerator().as<exact_integer>(); }
auto operator >=(exact_integer const& a, ratio const& b) -> bool { auto const x = ratio(b); return std::invoke(is_integer(), x) and a >= x.numerator().as<exact_integer>(); }
auto operator ==(exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) == 0; }
auto operator !=(exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) != 0; }
auto operator < (exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) > 0; }
auto operator <=(exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) >= 0; }
auto operator > (exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) < 0; }
auto operator >=(exact_integer const& a, ratio const& b) -> bool { return mpq_cmp_z(b.value, a.value) <= 0; }

auto operator + (exact_integer const& a, float b) -> float { return inexact_cast(a) + b; }
auto operator - (exact_integer const& a, float b) -> float { return inexact_cast(a) - b; }
Expand All @@ -69,29 +69,29 @@ inline namespace kernel
auto operator > (exact_integer const& a, double b) -> bool { return mpz_cmp_d(a.value, b) > 0; }
auto operator >=(exact_integer const& a, double b) -> bool { return mpz_cmp_d(a.value, b) >= 0; }

auto operator * (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as<exact_integer>() * b), a.denominator()); }
auto operator + (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as<exact_integer>() + a.denominator().as<exact_integer>() * b), a.denominator()); }
auto operator - (ratio const& a, exact_integer const& b) -> ratio { return ratio(make(a.numerator().as<exact_integer>() - a.denominator().as<exact_integer>() * b), a.denominator()); }
auto operator / (ratio const& a, exact_integer const& b) -> ratio { return ratio(a.numerator(), make(a.denominator().as<exact_integer>() * b)); }
auto operator + (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_add(q.value, a.value, ratio(b).value); return q; }
auto operator - (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_sub(q.value, a.value, ratio(b).value); return q; }
auto operator * (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_mul(q.value, a.value, ratio(b).value); return q; }
auto operator / (ratio const& a, exact_integer const& b) -> ratio { ratio q; mpq_div(q.value, a.value, ratio(b).value); return q; }
auto operator % (ratio const& , exact_integer const& ) -> ratio { throw error(make<string>("unsupported operation"), unit); }
auto operator !=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as<exact_integer>() != b; }
auto operator < (ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as<exact_integer>() < b; }
auto operator <=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as<exact_integer>() <= b; }
auto operator ==(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as<exact_integer>() == b; }
auto operator > (ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as<exact_integer>() > b; }
auto operator >=(ratio const& a, exact_integer const& b) -> bool { auto const x = ratio(a); return std::invoke(is_integer(), x) and x.numerator().as<exact_integer>() >= b; }

auto operator + (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>() + b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()), make(a.denominator().as<exact_integer>() * b.denominator().as<exact_integer>())); }
auto operator - (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>() - b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()), make(a.denominator().as<exact_integer>() * b.denominator().as<exact_integer>())); }
auto operator * (ratio const& a, ratio const& b) -> ratio { return ratio(make(a.numerator().as<exact_integer>() * b.numerator().as<exact_integer>()), make(a.denominator().as<exact_integer>() * b.denominator().as<exact_integer>())); }
auto operator / (ratio const& a, ratio const& b) -> ratio { return a * b.invert(); }
auto operator ==(ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) == 0; }
auto operator !=(ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) != 0; }
auto operator < (ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) < 0; }
auto operator <=(ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) <= 0; }
auto operator > (ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) > 0; }
auto operator >=(ratio const& a, exact_integer const& b) -> bool { return mpq_cmp_z(a.value, b.value) >= 0; }

auto operator + (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_add(q.value, a.value, b.value); return q; }
auto operator - (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_sub(q.value, a.value, b.value); return q; }
auto operator * (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_mul(q.value, a.value, b.value); return q; }
auto operator / (ratio const& a, ratio const& b) -> ratio { ratio q; mpq_div(q.value, a.value, b.value); return q; }
auto operator % (ratio const& , ratio const& ) -> ratio { throw error(make<string>("unsupported operation"), unit); }
auto operator ==(ratio const& a, ratio const& b) -> bool { return (a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>()) == (b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()); }
auto operator !=(ratio const& a, ratio const& b) -> bool { return (a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>()) != (b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()); }
auto operator < (ratio const& a, ratio const& b) -> bool { return (a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>()) < (b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()); }
auto operator <=(ratio const& a, ratio const& b) -> bool { return (a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>()) <= (b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()); }
auto operator > (ratio const& a, ratio const& b) -> bool { return (a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>()) > (b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()); }
auto operator >=(ratio const& a, ratio const& b) -> bool { return (a.numerator().as<exact_integer>() * b.denominator().as<exact_integer>()) >= (b.numerator().as<exact_integer>() * a.denominator().as<exact_integer>()); }
auto operator ==(ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) == 0; }
auto operator !=(ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) != 0; }
auto operator < (ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) < 0; }
auto operator <=(ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) <= 0; }
auto operator > (ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) > 0; }
auto operator >=(ratio const& a, ratio const& b) -> bool { return mpq_cmp(a.value, b.value) >= 0; }

auto operator + (ratio const& a, float b) -> float { return inexact_cast(a) + b; }
auto operator - (ratio const& a, float b) -> float { return inexact_cast(a) - b; }
Expand Down Expand Up @@ -148,10 +148,10 @@ inline namespace kernel
auto operator % (double a, exact_integer const& b) -> double { return std::remainder(a, inexact_cast(b)); }
auto operator ==(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) == 0; }
auto operator !=(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) != 0; }
auto operator < (double a, exact_integer const& b) -> bool { return a < inexact_cast(b); }
auto operator <=(double a, exact_integer const& b) -> bool { return a <= inexact_cast(b); }
auto operator > (double a, exact_integer const& b) -> bool { return a > inexact_cast(b); }
auto operator >=(double a, exact_integer const& b) -> bool { return a >= inexact_cast(b); }
auto operator < (double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) > 0; }
auto operator <=(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) >= 0; }
auto operator > (double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) < 0; }
auto operator >=(double a, exact_integer const& b) -> bool { return mpz_cmp_d(b.value, a) <= 0; }

auto operator + (double a, ratio const& b) -> double { return a + inexact_cast(b); }
auto operator - (double a, ratio const& b) -> double { return a - inexact_cast(b); }
Expand Down
26 changes: 17 additions & 9 deletions src/kernel/ratio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,17 @@ inline namespace kernel
mpq_canonicalize(value);
}

ratio::ratio(const_reference x, const_reference y)
ratio::ratio(exact_integer const& z)
{
mpq_init(value);
mpq_set_num(value, x.as<exact_integer>().value);
mpq_set_den(value, y.as<exact_integer>().value);
mpq_set_z(value, z.value);
}

ratio::ratio(exact_integer const& n, exact_integer const& d)
{
mpq_init(value);
mpq_set_num(value, n.value);
mpq_set_den(value, d.value);
mpq_canonicalize(value);
}

Expand Down Expand Up @@ -80,11 +86,6 @@ inline namespace kernel
return make<exact_integer>(mpq_denref(value));
}

auto ratio::invert() const -> ratio
{
return ratio(denominator(), numerator());
}

auto ratio::numerator() const -> value_type
{
return make<exact_integer>(mpq_numref(value));
Expand All @@ -97,7 +98,14 @@ inline namespace kernel

auto operator <<(std::ostream & os, ratio const& datum) -> std::ostream &
{
return os << datum.numerator() << cyan("/") << datum.denominator();
auto free = [](char * data)
{
void (*free)(void *, std::size_t);
mp_get_memory_functions(nullptr, nullptr, &free);
std::invoke(free, static_cast<void *>(data), std::strlen(data) + 1);
};

return os << cyan(std::unique_ptr<char, decltype(free)>(mpq_get_str(nullptr, 10, datum.value), free).get());
}
} // namespace kernel
} // namespace meevax
2 changes: 1 addition & 1 deletion test/numerical-operations.ss
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

(let ((x (+ 1 1/2)))

(check x => 3/2)
(check x (=> =) 3/2)

(check (number? x) => #t)
(check (complex? x) => #t)
Expand Down

0 comments on commit ad67f24

Please sign in to comment.