Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Imaginary-base-numbers/00-META.yaml
Normal file
2
Task/Imaginary-base-numbers/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Imaginary_base_numbers
|
||||
310
Task/Imaginary-base-numbers/00-TASK.txt
Normal file
310
Task/Imaginary-base-numbers/00-TASK.txt
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
Imaginary base numbers are a non-standard positional numeral system which uses an imaginary number as its radix. The most common is quater-imaginary with radix 2i.
|
||||
|
||||
''The quater-imaginary numeral system was first proposed by [https://en.wikipedia.org/wiki/Donald_Knuth Donald Knuth] in 1955 as a submission for a high school science talent search. [http://www.fact-index.com/q/qu/quater_imaginary_base.html [Ref.]]''
|
||||
|
||||
Other imaginary bases are possible too but are not as widely discussed and aren't specifically named.
|
||||
|
||||
'''Task:''' Write a set of procedures (functions, subroutines, however they are referred to in your language) to convert base 10 numbers to an imaginary base and back.
|
||||
|
||||
At a minimum, support quater-imaginary (base 2i).
|
||||
|
||||
For extra kudos, support positive or negative bases 2i through 6i (or higher).
|
||||
|
||||
As a stretch goal, support converting non-integer numbers ( E.G. 227.65625+10.859375i ) to an imaginary base.
|
||||
|
||||
See [https://en.wikipedia.org/wiki/Quater-imaginary_base Wikipedia: Quater-imaginary_base] for more details.
|
||||
|
||||
For reference, here are some some decimal and complex numbers converted to quater-imaginary.
|
||||
<table class="multicol" role="presentation" style="border-collapse: collapse; padding: 0; border: 0; background:transparent; width:100%;">
|
||||
<tr>
|
||||
<td style="text-align: left; vertical-align: top;">
|
||||
<table class="wikitable" style="text-align:right">
|
||||
<tr>
|
||||
<th>Base 10</th>
|
||||
<th>Base 2<i>i</i></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td><i> </i>1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td><i> </i>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td><i> </i>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4</td>
|
||||
<td><i> </i>10300</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5</td>
|
||||
<td><i> </i>10301</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
<td><i> </i>10302</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7</td>
|
||||
<td><i> </i>10303</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8</td>
|
||||
<td><i> </i>10200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>9</td>
|
||||
<td><i> </i>10201</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10</td>
|
||||
<td><i> </i>10202</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>11</td>
|
||||
<td><i> </i>10203</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>12</td>
|
||||
<td><i> </i>10100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13</td>
|
||||
<td><i> </i>10101</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>14</td>
|
||||
<td><i> </i>10102</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>15</td>
|
||||
<td><i> </i>10103</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>16</td>
|
||||
<td><i> </i>10000</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="text-align: left; vertical-align: top;">
|
||||
<table class="wikitable" style="text-align:right">
|
||||
<tr>
|
||||
<th>Base 10</th>
|
||||
<th>Base 2<i>i</i></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−1</td>
|
||||
<td><i> </i>103</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−2</td>
|
||||
<td><i> </i>102</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−3</td>
|
||||
<td><i> </i>101</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−4</td>
|
||||
<td><i> </i>100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−5</td>
|
||||
<td><i> </i>203</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−6</td>
|
||||
<td><i> </i>202</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−7</td>
|
||||
<td><i> </i>201</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−8</td>
|
||||
<td><i> </i>200</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−9</td>
|
||||
<td><i> </i>303</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10</td>
|
||||
<td><i> </i>302</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−11</td>
|
||||
<td><i> </i>301</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−12</td>
|
||||
<td><i> </i>300</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−13</td>
|
||||
<td><i> </i>1030003</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−14</td>
|
||||
<td><i> </i>1030002</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−15</td>
|
||||
<td><i> </i>1030001</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−16</td>
|
||||
<td><i> </i>1030000</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="text-align: left; vertical-align: top;">
|
||||
<table class="wikitable" style="text-align:right">
|
||||
<tr>
|
||||
<th>Base 10</th>
|
||||
<th>Base 2<i>i</i></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1<i>i</i></td>
|
||||
<td>10.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2<i>i</i></td>
|
||||
<td>10.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3<i>i</i></td>
|
||||
<td>20.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4<i>i</i></td>
|
||||
<td>20.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5<i>i</i></td>
|
||||
<td>30.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6<i>i</i></td>
|
||||
<td>30.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7<i>i</i></td>
|
||||
<td>103000.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8<i>i</i></td>
|
||||
<td>103000.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>9<i>i</i></td>
|
||||
<td>103010.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10<i>i</i></td>
|
||||
<td>103010.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>11<i>i</i></td>
|
||||
<td>103020.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>12<i>i</i></td>
|
||||
<td>103020.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13<i>i</i></td>
|
||||
<td>103030.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>14<i>i</i></td>
|
||||
<td>103030.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>15<i>i</i></td>
|
||||
<td>102000.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>16<i>i</i></td>
|
||||
<td>102000.0</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="text-align: left; vertical-align: top;">
|
||||
<table class="wikitable" style="text-align:right">
|
||||
<tr>
|
||||
<th>Base 10</th>
|
||||
<th>Base 2<i>i</i></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−1<i>i</i></td>
|
||||
<td>0.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−2<i>i</i></td>
|
||||
<td>1030.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−3<i>i</i></td>
|
||||
<td>1030.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−4<i>i</i></td>
|
||||
<td>1020.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−5<i>i</i></td>
|
||||
<td>1020.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−6<i>i</i></td>
|
||||
<td>1010.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−7<i>i</i></td>
|
||||
<td>1010.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−8<i>i</i></td>
|
||||
<td>1000.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−9<i>i</i></td>
|
||||
<td>1000.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−10<i>i</i></td>
|
||||
<td>2030.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−11<i>i</i></td>
|
||||
<td>2030.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−12<i>i</i></td>
|
||||
<td>2020.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−13<i>i</i></td>
|
||||
<td>2020.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−14<i>i</i></td>
|
||||
<td>2010.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−15<i>i</i></td>
|
||||
<td>2010.2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>−16<i>i</i></td>
|
||||
<td>2000.0</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
99
Task/Imaginary-base-numbers/11l/imaginary-base-numbers.11l
Normal file
99
Task/Imaginary-base-numbers/11l/imaginary-base-numbers.11l
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
F inv(c)
|
||||
V denom = c.real * c.real + c.imag * c.imag
|
||||
R Complex(c.real / denom, -c.imag / denom)
|
||||
|
||||
T QuaterImaginary
|
||||
:twoI = Complex(0, 2)
|
||||
:invTwoI = inv(.:twoI)
|
||||
|
||||
String b2i
|
||||
|
||||
F (str)
|
||||
I !re:‘[0123.]+’.match(str) | str.count(‘.’) > 1
|
||||
assert(0B, ‘Invalid base 2i number’)
|
||||
.b2i = str
|
||||
|
||||
F toComplex()
|
||||
V pointPos = .b2i.findi(‘.’)
|
||||
V posLen = I (pointPos < 0) {.b2i.len} E pointPos
|
||||
V sum = Complex(0, 0)
|
||||
V prod = Complex(1, 0)
|
||||
L(j) 0 .< posLen
|
||||
V k = Int(.b2i[posLen - 1 - j])
|
||||
I k > 0
|
||||
sum += prod * k
|
||||
prod *= .:twoI
|
||||
I pointPos != -1
|
||||
prod = .:invTwoI
|
||||
L(j) posLen + 1 .< .b2i.len
|
||||
V k = Int(.b2i[j])
|
||||
I k > 0
|
||||
sum += prod * k
|
||||
prod *= .:invTwoI
|
||||
R sum
|
||||
|
||||
F String()
|
||||
R String(.b2i)
|
||||
|
||||
F toQuaterImaginary(c)
|
||||
I c.real == 0.0 & c.imag == 0.0
|
||||
R QuaterImaginary(‘0’)
|
||||
|
||||
V re = Int(c.real)
|
||||
V im = Int(c.imag)
|
||||
V fi = -1
|
||||
V ss = ‘’
|
||||
L re != 0
|
||||
(re, V rem) = divmod(re, -4)
|
||||
I rem < 0
|
||||
rem += 4
|
||||
re++
|
||||
ss ‘’= String(rem)‘0’
|
||||
I im != 0
|
||||
V f = c.imag / 2
|
||||
im = Int(ceil(f))
|
||||
f = -4 * (f - im)
|
||||
V index = 1
|
||||
L im != 0
|
||||
(im, V rem) = divmod(im, -4)
|
||||
I rem < 0
|
||||
rem += 4
|
||||
im++
|
||||
I index < ss.len
|
||||
assert(0B)
|
||||
E
|
||||
ss ‘’= ‘0’String(rem)
|
||||
index = index + 2
|
||||
fi = Int(f)
|
||||
ss = reversed(ss)
|
||||
I fi != -1
|
||||
ss ‘’= ‘.’String(fi)
|
||||
ss = ss.ltrim(‘0’)
|
||||
I ss[0] == ‘.’
|
||||
ss = ‘0’ss
|
||||
R QuaterImaginary(ss)
|
||||
|
||||
L(i) 1..16
|
||||
V c1 = Complex(i, 0)
|
||||
V qi = toQuaterImaginary(c1)
|
||||
V c2 = qi.toComplex()
|
||||
print(‘#8 -> #8 -> #8 ’.format(c1, qi, c2), end' ‘ ’)
|
||||
|
||||
c1 = -c1
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = qi.toComplex()
|
||||
print(‘#8 -> #8 -> #8’.format(c1, qi, c2))
|
||||
print()
|
||||
|
||||
L(i) 1..16
|
||||
V c1 = Complex(0, i)
|
||||
V qi = toQuaterImaginary(c1)
|
||||
V c2 = qi.toComplex()
|
||||
print(‘#8 -> #8 -> #8 ’.format(c1, qi, c2), end' ‘ ’)
|
||||
|
||||
c1 = -c1
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = qi.toComplex()
|
||||
print(‘#8 -> #8 -> #8’.format(c1, qi, c2))
|
||||
|
||||
print(‘done’)
|
||||
145
Task/Imaginary-base-numbers/C++/imaginary-base-numbers.cpp
Normal file
145
Task/Imaginary-base-numbers/C++/imaginary-base-numbers.cpp
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#include <algorithm>
|
||||
#include <complex>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
std::complex<double> inv(const std::complex<double>& c) {
|
||||
double denom = c.real() * c.real() + c.imag() * c.imag();
|
||||
return std::complex<double>(c.real() / denom, -c.imag() / denom);
|
||||
}
|
||||
|
||||
class QuaterImaginary {
|
||||
public:
|
||||
QuaterImaginary(const std::string& s) : b2i(s) {
|
||||
static std::string base("0123.");
|
||||
|
||||
if (b2i.empty()
|
||||
|| std::any_of(s.cbegin(), s.cend(), [](char c) { return base.find(c) == std::string::npos; })
|
||||
|| std::count(s.cbegin(), s.cend(), '.') > 1) {
|
||||
throw std::runtime_error("Invalid base 2i number");
|
||||
}
|
||||
}
|
||||
|
||||
QuaterImaginary& operator=(const QuaterImaginary& q) {
|
||||
b2i = q.b2i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::complex<double> toComplex() const {
|
||||
int pointPos = b2i.find('.');
|
||||
int posLen = (pointPos != std::string::npos) ? pointPos : b2i.length();
|
||||
std::complex<double> sum(0.0, 0.0);
|
||||
std::complex<double> prod(1.0, 0.0);
|
||||
for (int j = 0; j < posLen; j++) {
|
||||
double k = (b2i[posLen - 1 - j] - '0');
|
||||
if (k > 0.0) {
|
||||
sum += prod * k;
|
||||
}
|
||||
prod *= twoI;
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = invTwoI;
|
||||
for (size_t j = posLen + 1; j < b2i.length(); j++) {
|
||||
double k = (b2i[j] - '0');
|
||||
if (k > 0.0) {
|
||||
sum += prod * k;
|
||||
}
|
||||
prod *= invTwoI;
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&, const QuaterImaginary&);
|
||||
|
||||
private:
|
||||
const std::complex<double> twoI{ 0.0, 2.0 };
|
||||
const std::complex<double> invTwoI = inv(twoI);
|
||||
|
||||
std::string b2i;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const QuaterImaginary& q) {
|
||||
return os << q.b2i;
|
||||
}
|
||||
|
||||
// only works properly if 'real' and 'imag' are both integral
|
||||
QuaterImaginary toQuaterImaginary(const std::complex<double>& c) {
|
||||
if (c.real() == 0.0 && c.imag() == 0.0) return QuaterImaginary("0");
|
||||
|
||||
int re = (int)c.real();
|
||||
int im = (int)c.imag();
|
||||
int fi = -1;
|
||||
std::stringstream ss;
|
||||
while (re != 0) {
|
||||
int rem = re % -4;
|
||||
re /= -4;
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem;
|
||||
re++;
|
||||
}
|
||||
ss << rem << 0;
|
||||
}
|
||||
if (im != 0) {
|
||||
double f = (std::complex<double>(0.0, c.imag()) / std::complex<double>(0.0, 2.0)).real();
|
||||
im = (int)ceil(f);
|
||||
f = -4.0 * (f - im);
|
||||
size_t index = 1;
|
||||
while (im != 0) {
|
||||
int rem = im % -4;
|
||||
im /= -4;
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem;
|
||||
im++;
|
||||
}
|
||||
if (index < ss.str().length()) {
|
||||
ss.str()[index] = (char)(rem + 48);
|
||||
} else {
|
||||
ss << 0 << rem;
|
||||
}
|
||||
index += 2;
|
||||
}
|
||||
fi = (int)f;
|
||||
}
|
||||
|
||||
auto r = ss.str();
|
||||
std::reverse(r.begin(), r.end());
|
||||
ss.str("");
|
||||
ss.clear();
|
||||
ss << r;
|
||||
if (fi != -1) ss << '.' << fi;
|
||||
r = ss.str();
|
||||
r.erase(r.begin(), std::find_if(r.begin(), r.end(), [](char c) { return c != '0'; }));
|
||||
if (r[0] == '.')r = "0" + r;
|
||||
return QuaterImaginary(r);
|
||||
}
|
||||
|
||||
int main() {
|
||||
using namespace std;
|
||||
|
||||
for (int i = 1; i <= 16; i++) {
|
||||
complex<double> c1(i, 0);
|
||||
QuaterImaginary qi = toQuaterImaginary(c1);
|
||||
complex<double> c2 = qi.toComplex();
|
||||
cout << setw(8) << c1 << " -> " << setw(8) << qi << " -> " << setw(8) << c2 << " ";
|
||||
c1 = -c1;
|
||||
qi = toQuaterImaginary(c1);
|
||||
c2 = qi.toComplex();
|
||||
cout << setw(8) << c1 << " -> " << setw(8) << qi << " -> " << setw(8) << c2 << endl;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
for (int i = 1; i <= 16; i++) {
|
||||
complex<double> c1(0, i);
|
||||
QuaterImaginary qi = toQuaterImaginary(c1);
|
||||
complex<double> c2 = qi.toComplex();
|
||||
cout << setw(8) << c1 << " -> " << setw(8) << qi << " -> " << setw(8) << c2 << " ";
|
||||
c1 = -c1;
|
||||
qi = toQuaterImaginary(c1);
|
||||
c2 = qi.toComplex();
|
||||
cout << setw(8) << c1 << " -> " << setw(8) << qi << " -> " << setw(8) << c2 << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
177
Task/Imaginary-base-numbers/C-sharp/imaginary-base-numbers.cs
Normal file
177
Task/Imaginary-base-numbers/C-sharp/imaginary-base-numbers.cs
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ImaginaryBaseNumbers {
|
||||
class Complex {
|
||||
private double real, imag;
|
||||
|
||||
public Complex(int r, int i) {
|
||||
real = r;
|
||||
imag = i;
|
||||
}
|
||||
|
||||
public Complex(double r, double i) {
|
||||
real = r;
|
||||
imag = i;
|
||||
}
|
||||
|
||||
public static Complex operator -(Complex self) =>
|
||||
new Complex(-self.real, -self.imag);
|
||||
|
||||
public static Complex operator +(Complex rhs, Complex lhs) =>
|
||||
new Complex(rhs.real + lhs.real, rhs.imag + lhs.imag);
|
||||
|
||||
public static Complex operator -(Complex rhs, Complex lhs) =>
|
||||
new Complex(rhs.real - lhs.real, rhs.imag - lhs.imag);
|
||||
|
||||
public static Complex operator *(Complex rhs, Complex lhs) =>
|
||||
new Complex(
|
||||
rhs.real * lhs.real - rhs.imag * lhs.imag,
|
||||
rhs.real * lhs.imag + rhs.imag * lhs.real
|
||||
);
|
||||
|
||||
public static Complex operator *(Complex rhs, double lhs) =>
|
||||
new Complex(rhs.real * lhs, rhs.imag * lhs);
|
||||
|
||||
public static Complex operator /(Complex rhs, Complex lhs) =>
|
||||
rhs * lhs.Inv();
|
||||
|
||||
public Complex Inv() {
|
||||
double denom = real * real + imag * imag;
|
||||
return new Complex(real / denom, -imag / denom);
|
||||
}
|
||||
|
||||
public QuaterImaginary ToQuaterImaginary() {
|
||||
if (real == 0.0 && imag == 0.0) return new QuaterImaginary("0");
|
||||
int re = (int)real;
|
||||
int im = (int)imag;
|
||||
int fi = -1;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (re != 0) {
|
||||
int rem = re % -4;
|
||||
re /= -4;
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem;
|
||||
re++;
|
||||
}
|
||||
sb.Append(rem);
|
||||
sb.Append(0);
|
||||
}
|
||||
if (im != 0) {
|
||||
double f = (new Complex(0.0, imag) / new Complex(0.0, 2.0)).real;
|
||||
im = (int)Math.Ceiling(f);
|
||||
f = -4.0 * (f - im);
|
||||
int index = 1;
|
||||
while (im != 0) {
|
||||
int rem = im % -4;
|
||||
im /= -4;
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem;
|
||||
im++;
|
||||
}
|
||||
if (index < sb.Length) {
|
||||
sb[index] = (char)(rem + 48);
|
||||
} else {
|
||||
sb.Append(0);
|
||||
sb.Append(rem);
|
||||
}
|
||||
index += 2;
|
||||
}
|
||||
fi = (int)f;
|
||||
}
|
||||
string reverse = new string(sb.ToString().Reverse().ToArray());
|
||||
sb.Length = 0;
|
||||
sb.Append(reverse);
|
||||
if (fi != -1) sb.AppendFormat(".{0}", fi);
|
||||
string s = sb.ToString().TrimStart('0');
|
||||
if (s[0] == '.') s = "0" + s;
|
||||
return new QuaterImaginary(s);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
double real2 = (real == -0.0) ? 0.0 : real; // get rid of negative zero
|
||||
double imag2 = (imag == -0.0) ? 0.0 : imag; // ditto
|
||||
if (imag2 == 0.0) {
|
||||
return string.Format("{0}", real2);
|
||||
}
|
||||
if (real2 == 0.0) {
|
||||
return string.Format("{0}i", imag2);
|
||||
}
|
||||
if (imag2 > 0.0) {
|
||||
return string.Format("{0} + {1}i", real2, imag2);
|
||||
}
|
||||
return string.Format("{0} - {1}i", real2, -imag2);
|
||||
}
|
||||
}
|
||||
|
||||
class QuaterImaginary {
|
||||
internal static Complex twoI = new Complex(0.0, 2.0);
|
||||
internal static Complex invTwoI = twoI.Inv();
|
||||
|
||||
private string b2i;
|
||||
|
||||
public QuaterImaginary(string b2i) {
|
||||
if (b2i == "" || !b2i.All(c => "0123.".IndexOf(c) > -1) || b2i.Count(c => c == '.') > 1) {
|
||||
throw new Exception("Invalid Base 2i number");
|
||||
}
|
||||
this.b2i = b2i;
|
||||
}
|
||||
|
||||
public Complex ToComplex() {
|
||||
int pointPos = b2i.IndexOf(".");
|
||||
int posLen = (pointPos != -1) ? pointPos : b2i.Length;
|
||||
Complex sum = new Complex(0.0, 0.0);
|
||||
Complex prod = new Complex(1.0, 0.0);
|
||||
for (int j = 0; j < posLen; j++) {
|
||||
double k = (b2i[posLen - 1 - j] - '0');
|
||||
if (k > 0.0) {
|
||||
sum += prod * k;
|
||||
}
|
||||
prod *= twoI;
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = invTwoI;
|
||||
for (int j = posLen + 1; j < b2i.Length; j++) {
|
||||
double k = (b2i[j] - '0');
|
||||
if (k > 0.0) {
|
||||
sum += prod * k;
|
||||
}
|
||||
prod *= invTwoI;
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return b2i;
|
||||
}
|
||||
}
|
||||
|
||||
class Program {
|
||||
static void Main(string[] args) {
|
||||
for (int i = 1; i <= 16; i++) {
|
||||
Complex c1 = new Complex(i, 0);
|
||||
QuaterImaginary qi = c1.ToQuaterImaginary();
|
||||
Complex c2 = qi.ToComplex();
|
||||
Console.Write("{0,4} -> {1,8} -> {2,4} ", c1, qi, c2);
|
||||
c1 = -c1;
|
||||
qi = c1.ToQuaterImaginary();
|
||||
c2 = qi.ToComplex();
|
||||
Console.WriteLine("{0,4} -> {1,8} -> {2,4}", c1, qi, c2);
|
||||
}
|
||||
Console.WriteLine();
|
||||
for (int i = 1; i <= 16; i++) {
|
||||
Complex c1 = new Complex(0, i);
|
||||
QuaterImaginary qi = c1.ToQuaterImaginary();
|
||||
Complex c2 = qi.ToComplex();
|
||||
Console.Write("{0,4} -> {1,8} -> {2,4} ", c1, qi, c2);
|
||||
c1 = -c1;
|
||||
qi = c1.ToQuaterImaginary();
|
||||
c2 = qi.ToComplex();
|
||||
Console.WriteLine("{0,4} -> {1,8} -> {2,4}", c1, qi, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
269
Task/Imaginary-base-numbers/C/imaginary-base-numbers.c
Normal file
269
Task/Imaginary-base-numbers/C/imaginary-base-numbers.c
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int find(char *s, char c) {
|
||||
for (char *i = s; *i != 0; i++) {
|
||||
if (*i == c) {
|
||||
return i - s;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void reverse(char *b, char *e) {
|
||||
for (e--; b < e; b++, e--) {
|
||||
char t = *b;
|
||||
*b = *e;
|
||||
*e = t;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
struct Complex {
|
||||
double rel, img;
|
||||
};
|
||||
|
||||
void printComplex(struct Complex c) {
|
||||
printf("(%3.0f + %3.0fi)", c.rel, c.img);
|
||||
}
|
||||
|
||||
struct Complex makeComplex(double rel, double img) {
|
||||
struct Complex c = { rel, img };
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Complex addComplex(struct Complex a, struct Complex b) {
|
||||
struct Complex c = { a.rel + b.rel, a.img + b.img };
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Complex mulComplex(struct Complex a, struct Complex b) {
|
||||
struct Complex c = { a.rel * b.rel - a.img * b.img, a.rel * b.img - a.img * b.rel };
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Complex mulComplexD(struct Complex a, double b) {
|
||||
struct Complex c = { a.rel * b, a.img * b };
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Complex negComplex(struct Complex a) {
|
||||
return mulComplexD(a, -1.0);
|
||||
}
|
||||
|
||||
struct Complex divComplex(struct Complex a, struct Complex b) {
|
||||
double re = a.rel * b.rel + a.img * b.img;
|
||||
double im = a.img * b.rel - a.rel * b.img;
|
||||
double d = b.rel * b.rel + b.img * b.img;
|
||||
struct Complex c = { re / d, im / d };
|
||||
return c;
|
||||
}
|
||||
|
||||
struct Complex inv(struct Complex c) {
|
||||
double d = c.rel * c.rel + c.img * c.img;
|
||||
struct Complex i = { c.rel / d, -c.img / d };
|
||||
return i;
|
||||
}
|
||||
|
||||
const struct Complex TWO_I = { 0.0, 2.0 };
|
||||
const struct Complex INV_TWO_I = { 0.0, -0.5 };
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
struct QuaterImaginary {
|
||||
char *b2i;
|
||||
int valid;
|
||||
};
|
||||
|
||||
struct QuaterImaginary makeQuaterImaginary(char *s) {
|
||||
struct QuaterImaginary qi = { s, 0 }; // assume invalid until tested
|
||||
size_t i, valid = 1, cnt = 0;
|
||||
|
||||
if (*s != 0) {
|
||||
for (i = 0; s[i] != 0; i++) {
|
||||
if (s[i] < '0' || '3' < s[i]) {
|
||||
if (s[i] == '.') {
|
||||
cnt++;
|
||||
} else {
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (valid && cnt > 1) {
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
qi.valid = valid;
|
||||
return qi;
|
||||
}
|
||||
|
||||
void printQuaterImaginary(struct QuaterImaginary qi) {
|
||||
if (qi.valid) {
|
||||
printf("%8s", qi.b2i);
|
||||
} else {
|
||||
printf(" ERROR ");
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
struct Complex qi2c(struct QuaterImaginary qi) {
|
||||
size_t len = strlen(qi.b2i);
|
||||
int pointPos = find(qi.b2i, '.');
|
||||
size_t posLen = (pointPos > 0) ? pointPos : len;
|
||||
struct Complex sum = makeComplex(0.0, 0.0);
|
||||
struct Complex prod = makeComplex(1.0, 0.0);
|
||||
size_t j;
|
||||
|
||||
for (j = 0; j < posLen; j++) {
|
||||
double k = qi.b2i[posLen - 1 - j] - '0';
|
||||
if (k > 0.0) {
|
||||
sum = addComplex(sum, mulComplexD(prod, k));
|
||||
}
|
||||
prod = mulComplex(prod, TWO_I);
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = INV_TWO_I;
|
||||
for (j = posLen + 1; j < len; j++) {
|
||||
double k = qi.b2i[j] - '0';
|
||||
if (k > 0.0) {
|
||||
sum = addComplex(sum, mulComplexD(prod, k));
|
||||
}
|
||||
prod = mulComplex(prod, INV_TWO_I);
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
// only works properly if the real and imaginary parts are integral
|
||||
struct QuaterImaginary c2qi(struct Complex c, char *out) {
|
||||
char *p = out;
|
||||
int re, im, fi;
|
||||
|
||||
*p = 0;
|
||||
if (c.rel == 0.0 && c.img == 0.0) {
|
||||
return makeQuaterImaginary("0");
|
||||
}
|
||||
|
||||
re = (int)c.rel;
|
||||
im = (int)c.img;
|
||||
fi = -1;
|
||||
while (re != 0) {
|
||||
int rem = re % -4;
|
||||
re /= -4;
|
||||
if (rem < 0) {
|
||||
rem += 4;
|
||||
re++;
|
||||
}
|
||||
*p++ = rem + '0';
|
||||
*p++ = '0';
|
||||
*p = 0;
|
||||
}
|
||||
if (im != 0) {
|
||||
size_t index = 1;
|
||||
struct Complex fc = divComplex((struct Complex) { 0.0, c.img }, (struct Complex) { 0.0, 2.0 });
|
||||
double f = fc.rel;
|
||||
im = (int)ceil(f);
|
||||
f = -4.0 * (f - im);
|
||||
while (im != 0) {
|
||||
int rem = im % -4;
|
||||
im /= -4;
|
||||
if (rem < 0) {
|
||||
rem += 4;
|
||||
im++;
|
||||
}
|
||||
if (index < (p - out)) {
|
||||
out[index] = rem + '0';
|
||||
} else {
|
||||
*p++ = '0';
|
||||
*p++ = rem + '0';
|
||||
*p = 0;
|
||||
}
|
||||
index += 2;
|
||||
}
|
||||
fi = (int)f;
|
||||
}
|
||||
|
||||
reverse(out, p);
|
||||
if (fi != -1) {
|
||||
*p++ = '.';
|
||||
*p++ = fi + '0';
|
||||
*p = 0;
|
||||
}
|
||||
while (out[0] == '0' && out[1] != '.') {
|
||||
size_t i;
|
||||
for (i = 0; out[i] != 0; i++) {
|
||||
out[i] = out[i + 1];
|
||||
}
|
||||
}
|
||||
if (*out == '.') {
|
||||
reverse(out, p);
|
||||
*p++ = '0';
|
||||
*p = 0;
|
||||
reverse(out, p);
|
||||
}
|
||||
return makeQuaterImaginary(out);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
int main() {
|
||||
char buffer[16];
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= 16; i++) {
|
||||
struct Complex c1 = { i, 0.0 };
|
||||
struct QuaterImaginary qi = c2qi(c1, buffer);
|
||||
struct Complex c2 = qi2c(qi);
|
||||
printComplex(c1);
|
||||
printf(" -> ");
|
||||
printQuaterImaginary(qi);
|
||||
printf(" -> ");
|
||||
printComplex(c2);
|
||||
|
||||
printf(" ");
|
||||
|
||||
c1 = negComplex(c1);
|
||||
qi = c2qi(c1, buffer);
|
||||
c2 = qi2c(qi);
|
||||
printComplex(c1);
|
||||
printf(" -> ");
|
||||
printQuaterImaginary(qi);
|
||||
printf(" -> ");
|
||||
printComplex(c2);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
for (i = 1; i <= 16; i++) {
|
||||
struct Complex c1 = { 0.0, i };
|
||||
struct QuaterImaginary qi = c2qi(c1, buffer);
|
||||
struct Complex c2 = qi2c(qi);
|
||||
printComplex(c1);
|
||||
printf(" -> ");
|
||||
printQuaterImaginary(qi);
|
||||
printf(" -> ");
|
||||
printComplex(c2);
|
||||
|
||||
printf(" ");
|
||||
|
||||
c1 = negComplex(c1);
|
||||
qi = c2qi(c1, buffer);
|
||||
c2 = qi2c(qi);
|
||||
printComplex(c1);
|
||||
printf(" -> ");
|
||||
printQuaterImaginary(qi);
|
||||
printf(" -> ");
|
||||
printComplex(c2);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
153
Task/Imaginary-base-numbers/D/imaginary-base-numbers.d
Normal file
153
Task/Imaginary-base-numbers/D/imaginary-base-numbers.d
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
import std.algorithm;
|
||||
import std.array;
|
||||
import std.complex;
|
||||
import std.conv;
|
||||
import std.format;
|
||||
import std.math;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
|
||||
Complex!double inv(Complex!double v) {
|
||||
auto denom = v.re*v.re + v.im*v.im;
|
||||
return v.conj / denom;
|
||||
}
|
||||
|
||||
QuaterImaginary toQuaterImaginary(Complex!double v) {
|
||||
if (v.re == 0.0 && v.im == 0.0) return QuaterImaginary("0");
|
||||
auto re = v.re.to!int;
|
||||
auto im = v.im.to!int;
|
||||
auto fi = -1;
|
||||
auto sb = appender!(char[]);
|
||||
while (re != 0) {
|
||||
auto rem = re % -4;
|
||||
re /= -4;
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem;
|
||||
re++;
|
||||
}
|
||||
sb.formattedWrite("%d", rem);
|
||||
sb.put("0");
|
||||
}
|
||||
if (im != 0) {
|
||||
auto f = (complex(0.0, v.im) / complex(0.0, 2.0)).re;
|
||||
im = f.ceil.to!int;
|
||||
f = -4.0 * (f - im.to!double);
|
||||
auto index = 1;
|
||||
while (im != 0) {
|
||||
auto rem = im % -4;
|
||||
im /= -4;
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem;
|
||||
im++;
|
||||
}
|
||||
if (index < sb.data.length) {
|
||||
sb.data[index] = cast(char)(rem + '0');
|
||||
} else {
|
||||
sb.put("0");
|
||||
sb.formattedWrite("%d", rem);
|
||||
}
|
||||
index += 2;
|
||||
}
|
||||
fi = f.to!int;
|
||||
}
|
||||
sb.data.reverse;
|
||||
if (fi != -1) sb.formattedWrite(".%d", fi);
|
||||
int i;
|
||||
while (i < sb.data.length && sb.data[i] == '0') {
|
||||
i++;
|
||||
}
|
||||
auto s = sb.data[i..$].idup;
|
||||
if (s[0] == '.') s = "0" ~ s;
|
||||
return QuaterImaginary(s);
|
||||
}
|
||||
|
||||
struct QuaterImaginary {
|
||||
private string b2i;
|
||||
|
||||
this(string b2i) {
|
||||
if (b2i == "" || b2i.count('.') > 1) {
|
||||
throw new Exception("Invalid Base 2i number");
|
||||
}
|
||||
foreach (c; b2i) {
|
||||
if (!canFind("0123.", c)) {
|
||||
throw new Exception("Invalid Base 2i number");
|
||||
}
|
||||
}
|
||||
this.b2i = b2i;
|
||||
}
|
||||
|
||||
T opCast(T : Complex!double)() {
|
||||
auto pointPos = b2i.indexOf('.');
|
||||
size_t posLen;
|
||||
if (pointPos != -1) {
|
||||
posLen = pointPos;
|
||||
} else {
|
||||
posLen = b2i.length;
|
||||
}
|
||||
auto sum = complex(0.0, 0.0);
|
||||
auto prod = complex(1.0, 0.0);
|
||||
foreach (j; 0..posLen) {
|
||||
auto k = (b2i[posLen - 1 - j] - '0').to!double;
|
||||
if (k > 0.0) {
|
||||
sum += prod * k;
|
||||
}
|
||||
prod *= twoI;
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = invTwoI;
|
||||
foreach (j; posLen+1..b2i.length) {
|
||||
auto k = (b2i[j] - '0').to!double;
|
||||
if (k > 0.0) {
|
||||
sum += prod * k;
|
||||
}
|
||||
prod *= invTwoI;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) const {
|
||||
if (fmt.spec == 's') {
|
||||
for (int i=0; i<fmt.width-b2i.length; ++i) {
|
||||
sink(" ");
|
||||
}
|
||||
}
|
||||
sink(b2i);
|
||||
}
|
||||
|
||||
enum twoI = complex(0.0, 2.0);
|
||||
enum invTwoI = twoI.inv;
|
||||
}
|
||||
|
||||
unittest {
|
||||
import std.exception;
|
||||
assertThrown!Exception(QuaterImaginary(""));
|
||||
assertThrown!Exception(QuaterImaginary("1.2.3"));
|
||||
assertThrown!Exception(QuaterImaginary("a"));
|
||||
assertThrown!Exception(QuaterImaginary("4"));
|
||||
assertThrown!Exception(QuaterImaginary(" "));
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (i; 1..17) {
|
||||
auto c1 = complex(i, 0);
|
||||
auto qi = c1.toQuaterImaginary;
|
||||
auto c2 = cast(Complex!double) qi;
|
||||
writef("%4s -> %8s -> %4s ", c1.re, qi, c2.re);
|
||||
c1 = -c1;
|
||||
qi = c1.toQuaterImaginary();
|
||||
c2 = cast(Complex!double) qi;
|
||||
writefln("%4s -> %8s -> %4s", c1.re, qi, c2.re);
|
||||
}
|
||||
writeln;
|
||||
foreach (i; 1..17) {
|
||||
auto c1 = complex(0, i);
|
||||
auto qi = c1.toQuaterImaginary;
|
||||
auto c2 = qi.to!(Complex!double);
|
||||
writef("%4si -> %8s -> %4si ", c1.im, qi, c2.im);
|
||||
c1 = -c1;
|
||||
qi = c1.toQuaterImaginary();
|
||||
c2 = cast(Complex!double) qi;
|
||||
writefln("%4si -> %8s -> %4si", c1.im, qi, c2.im);
|
||||
}
|
||||
}
|
||||
147
Task/Imaginary-base-numbers/Go/imaginary-base-numbers.go
Normal file
147
Task/Imaginary-base-numbers/Go/imaginary-base-numbers.go
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
twoI = 2.0i
|
||||
invTwoI = 1.0 / twoI
|
||||
)
|
||||
|
||||
type quaterImaginary struct {
|
||||
b2i string
|
||||
}
|
||||
|
||||
func reverse(s string) string {
|
||||
r := []rune(s)
|
||||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
||||
r[i], r[j] = r[j], r[i]
|
||||
}
|
||||
return string(r)
|
||||
}
|
||||
|
||||
func newQuaterImaginary(b2i string) quaterImaginary {
|
||||
b2i = strings.TrimSpace(b2i)
|
||||
_, err := strconv.ParseFloat(b2i, 64)
|
||||
if err != nil {
|
||||
panic("invalid Base 2i number")
|
||||
}
|
||||
return quaterImaginary{b2i}
|
||||
}
|
||||
|
||||
func toComplex(q quaterImaginary) complex128 {
|
||||
pointPos := strings.Index(q.b2i, ".")
|
||||
var posLen int
|
||||
if pointPos != -1 {
|
||||
posLen = pointPos
|
||||
} else {
|
||||
posLen = len(q.b2i)
|
||||
}
|
||||
sum := 0.0i
|
||||
prod := complex(1.0, 0.0)
|
||||
for j := 0; j < posLen; j++ {
|
||||
k := float64(q.b2i[posLen-1-j] - '0')
|
||||
if k > 0.0 {
|
||||
sum += prod * complex(k, 0.0)
|
||||
}
|
||||
prod *= twoI
|
||||
}
|
||||
if pointPos != -1 {
|
||||
prod = invTwoI
|
||||
for j := posLen + 1; j < len(q.b2i); j++ {
|
||||
k := float64(q.b2i[j] - '0')
|
||||
if k > 0.0 {
|
||||
sum += prod * complex(k, 0.0)
|
||||
}
|
||||
prod *= invTwoI
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func (q quaterImaginary) String() string {
|
||||
return q.b2i
|
||||
}
|
||||
|
||||
// only works properly if 'real' and 'imag' are both integral
|
||||
func toQuaterImaginary(c complex128) quaterImaginary {
|
||||
if c == 0i {
|
||||
return quaterImaginary{"0"}
|
||||
}
|
||||
re := int(real(c))
|
||||
im := int(imag(c))
|
||||
fi := -1
|
||||
var sb strings.Builder
|
||||
for re != 0 {
|
||||
rem := re % -4
|
||||
re /= -4
|
||||
if rem < 0 {
|
||||
rem += 4
|
||||
re++
|
||||
}
|
||||
sb.WriteString(strconv.Itoa(rem))
|
||||
sb.WriteString("0")
|
||||
}
|
||||
if im != 0 {
|
||||
f := real(complex(0.0, imag(c)) / 2.0i)
|
||||
im = int(math.Ceil(f))
|
||||
f = -4.0 * (f - float64(im))
|
||||
index := 1
|
||||
for im != 0 {
|
||||
rem := im % -4
|
||||
im /= -4
|
||||
if rem < 0 {
|
||||
rem += 4
|
||||
im++
|
||||
}
|
||||
if index < sb.Len() {
|
||||
bs := []byte(sb.String())
|
||||
bs[index] = byte(rem + 48)
|
||||
sb.Reset()
|
||||
sb.Write(bs)
|
||||
} else {
|
||||
sb.WriteString("0")
|
||||
sb.WriteString(strconv.Itoa(rem))
|
||||
}
|
||||
index += 2
|
||||
}
|
||||
fi = int(f)
|
||||
}
|
||||
s := reverse(sb.String())
|
||||
if fi != -1 {
|
||||
s = fmt.Sprintf("%s.%d", s, fi)
|
||||
}
|
||||
s = strings.TrimLeft(s, "0")
|
||||
if s[0] == '.' {
|
||||
s = "0" + s
|
||||
}
|
||||
return newQuaterImaginary(s)
|
||||
}
|
||||
|
||||
func main() {
|
||||
for i := 1; i <= 16; i++ {
|
||||
c1 := complex(float64(i), 0.0)
|
||||
qi := toQuaterImaginary(c1)
|
||||
c2 := toComplex(qi)
|
||||
fmt.Printf("%4.0f -> %8s -> %4.0f ", real(c1), qi, real(c2))
|
||||
c1 = -c1
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = toComplex(qi)
|
||||
fmt.Printf("%4.0f -> %8s -> %4.0f\n", real(c1), qi, real(c2))
|
||||
}
|
||||
fmt.Println()
|
||||
for i := 1; i <= 16; i++ {
|
||||
c1 := complex(0.0, float64(i))
|
||||
qi := toQuaterImaginary(c1)
|
||||
c2 := toComplex(qi)
|
||||
fmt.Printf("%3.0fi -> %8s -> %3.0fi ", imag(c1), qi, imag(c2))
|
||||
c1 = -c1
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = toComplex(qi)
|
||||
fmt.Printf("%3.0fi -> %8s -> %3.0fi\n", imag(c1), qi, imag(c2))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import Data.Char (chr, digitToInt, intToDigit, isDigit, ord)
|
||||
import Data.Complex (Complex (..), imagPart, realPart)
|
||||
import Data.List (delete, elemIndex)
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
||||
base :: Complex Float
|
||||
base = 0 :+ 2
|
||||
|
||||
quotRemPositive :: Int -> Int -> (Int, Int)
|
||||
quotRemPositive a b
|
||||
| r < 0 = (1 + q, floor (realPart (-base ^^ 2)) + r)
|
||||
| otherwise = (q, r)
|
||||
where
|
||||
(q, r) = quotRem a b
|
||||
|
||||
digitToIntQI :: Char -> Int
|
||||
digitToIntQI c
|
||||
| isDigit c = digitToInt c
|
||||
| otherwise = ord c - ord 'a' + 10
|
||||
|
||||
shiftRight :: String -> String
|
||||
shiftRight n
|
||||
| l == '0' = h
|
||||
| otherwise = h <> ('.' : [l])
|
||||
where
|
||||
(l, h) = (last n, init n)
|
||||
|
||||
intToDigitQI :: Int -> Char
|
||||
intToDigitQI i
|
||||
| i `elem` [0 .. 9] = intToDigit i
|
||||
| otherwise = chr (i - 10 + ord 'a')
|
||||
|
||||
fromQItoComplex :: String -> Complex Float -> Complex Float
|
||||
fromQItoComplex num b =
|
||||
let dot = fromMaybe (length num) (elemIndex '.' num)
|
||||
in fst $
|
||||
foldl
|
||||
( \(a, indx) x ->
|
||||
( a + fromIntegral (digitToIntQI x)
|
||||
* (b ^^ (dot - indx)),
|
||||
indx + 1
|
||||
)
|
||||
)
|
||||
(0, 1)
|
||||
(delete '.' num)
|
||||
|
||||
euclidEr :: Int -> Int -> [Int] -> [Int]
|
||||
euclidEr a b l
|
||||
| a == 0 = l
|
||||
| otherwise =
|
||||
let (q, r) = quotRemPositive a b
|
||||
in euclidEr q b (0 : r : l)
|
||||
|
||||
fromIntToQI :: Int -> [Int]
|
||||
fromIntToQI 0 = [0]
|
||||
fromIntToQI x =
|
||||
tail
|
||||
( euclidEr
|
||||
x
|
||||
(floor $ realPart (base ^^ 2))
|
||||
[]
|
||||
)
|
||||
|
||||
getCuid :: Complex Int -> Int
|
||||
getCuid c = imagPart c * floor (imagPart (-base))
|
||||
|
||||
qizip :: Complex Int -> [Int]
|
||||
qizip c =
|
||||
let (r, i) =
|
||||
( fromIntToQI (realPart c) <> [0],
|
||||
fromIntToQI (getCuid c)
|
||||
)
|
||||
in let m = min (length r) (length i)
|
||||
in take (length r - m) r
|
||||
<> take (length i - m) i
|
||||
<> reverse
|
||||
( zipWith
|
||||
(+)
|
||||
(take m (reverse r))
|
||||
(take m (reverse i))
|
||||
)
|
||||
|
||||
fromComplexToQI :: Complex Int -> String
|
||||
fromComplexToQI = shiftRight . fmap intToDigitQI . qizip
|
||||
|
||||
main :: IO ()
|
||||
main =
|
||||
putStrLn (fromComplexToQI (35 :+ 23))
|
||||
>> print (fromQItoComplex "10.2" base)
|
||||
19
Task/Imaginary-base-numbers/J/imaginary-base-numbers-1.j
Normal file
19
Task/Imaginary-base-numbers/J/imaginary-base-numbers-1.j
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
ibdec=: {{
|
||||
0j2 ibdec y
|
||||
:
|
||||
digits=. 0,".,~&'36b'@> tolower y -.'. '
|
||||
(x #. digits) % x^#(}.~ 1+i.&'.')y-.' '
|
||||
}}"1
|
||||
|
||||
ibenc=: {{
|
||||
0j2 ibenc y
|
||||
:
|
||||
if.0=y do.,'0' return.end.
|
||||
sq=.*:x assert. 17 > sq
|
||||
step=. }.,~(1,|sq) +^:(0>{:@]) (0,sq) #: {.
|
||||
seq=. step^:(0~:{.)^:_"0
|
||||
're im0'=.+.y
|
||||
'im imf'=.(sign,1)*(0,|x)#:im0*sign=.*im0
|
||||
frac=. ,hfd (imf*|x)-.0 if.#frac do.frac=.'.',frac end.
|
||||
frac,~(}.~0 i.~_1}.'0'=]) }:,hfd|:0 1|."0 1 seq re,im
|
||||
}}"0
|
||||
41
Task/Imaginary-base-numbers/J/imaginary-base-numbers-2.j
Normal file
41
Task/Imaginary-base-numbers/J/imaginary-base-numbers-2.j
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
(ibenc i:16),.' ',.ibenc j.i:16
|
||||
1030000 2000
|
||||
1030001 2010.2
|
||||
1030002 2010
|
||||
1030003 2020.2
|
||||
300 2020
|
||||
301 2030.2
|
||||
302 2030
|
||||
303 1000.2
|
||||
200 1000
|
||||
201 1010.2
|
||||
202 1010
|
||||
203 1020.2
|
||||
100 1020
|
||||
101 1030.2
|
||||
102 1030
|
||||
103 0.2
|
||||
0 0
|
||||
1 0.2
|
||||
2 10
|
||||
3 10.2
|
||||
10300 20
|
||||
10301 20.2
|
||||
10302 30
|
||||
10303 30.2
|
||||
10200 103000
|
||||
10201 103000.2
|
||||
10202 103010
|
||||
10203 103010.2
|
||||
10100 103020
|
||||
10101 103020.2
|
||||
10102 103030
|
||||
10103 103030.2
|
||||
10000 102000
|
||||
(ibdec ibenc i:16),:ibdec ibenc j.i:16
|
||||
_16 _15 _14 _13 _12 _11 _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
||||
0j_16 0j_15 0j_14 0j_13 0j_12 0j_11 0j_10 0j_9 0j_8 0j_7 0j_6 0j_5 0j_4 0j_3 0j_2 0j_1 0 0j_1 0j2 0j1 0j4 0j3 0j6 0j5 0j8 0j7 0j10 0j9 0j12 0j11 0j14 0j13 0j16
|
||||
0j4 ibenc 42
|
||||
10e0a
|
||||
0j4 ibdec 0j4 ibenc 42
|
||||
42
|
||||
178
Task/Imaginary-base-numbers/Java/imaginary-base-numbers.java
Normal file
178
Task/Imaginary-base-numbers/Java/imaginary-base-numbers.java
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
public class ImaginaryBaseNumber {
|
||||
private static class Complex {
|
||||
private Double real, imag;
|
||||
|
||||
public Complex(double r, double i) {
|
||||
this.real = r;
|
||||
this.imag = i;
|
||||
}
|
||||
|
||||
public Complex(int r, int i) {
|
||||
this.real = (double) r;
|
||||
this.imag = (double) i;
|
||||
}
|
||||
|
||||
public Complex add(Complex rhs) {
|
||||
return new Complex(
|
||||
real + rhs.real,
|
||||
imag + rhs.imag
|
||||
);
|
||||
}
|
||||
|
||||
public Complex times(Complex rhs) {
|
||||
return new Complex(
|
||||
real * rhs.real - imag * rhs.imag,
|
||||
real * rhs.imag + imag * rhs.real
|
||||
);
|
||||
}
|
||||
|
||||
public Complex times(double rhs) {
|
||||
return new Complex(
|
||||
real * rhs,
|
||||
imag * rhs
|
||||
);
|
||||
}
|
||||
|
||||
public Complex inv() {
|
||||
double denom = real * real + imag * imag;
|
||||
return new Complex(
|
||||
real / denom,
|
||||
-imag / denom
|
||||
);
|
||||
}
|
||||
|
||||
public Complex unaryMinus() {
|
||||
return new Complex(-real, -imag);
|
||||
}
|
||||
|
||||
public Complex divide(Complex rhs) {
|
||||
return this.times(rhs.inv());
|
||||
}
|
||||
|
||||
// only works properly if 'real' and 'imag' are both integral
|
||||
public QuaterImaginary toQuaterImaginary() {
|
||||
if (real == 0.0 && imag == 0.0) return new QuaterImaginary("0");
|
||||
int re = real.intValue();
|
||||
int im = imag.intValue();
|
||||
int fi = -1;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (re != 0) {
|
||||
int rem = re % -4;
|
||||
re /= -4;
|
||||
if (rem < 0) {
|
||||
rem += 4;
|
||||
re++;
|
||||
}
|
||||
sb.append(rem);
|
||||
sb.append(0);
|
||||
}
|
||||
if (im != 0) {
|
||||
Double f = new Complex(0.0, imag).divide(new Complex(0.0, 2.0)).real;
|
||||
im = ((Double) Math.ceil(f)).intValue();
|
||||
f = -4.0 * (f - im);
|
||||
int index = 1;
|
||||
while (im != 0) {
|
||||
int rem = im % -4;
|
||||
im /= -4;
|
||||
if (rem < 0) {
|
||||
rem += 4;
|
||||
im++;
|
||||
}
|
||||
if (index < sb.length()) {
|
||||
sb.setCharAt(index, (char) (rem + 48));
|
||||
} else {
|
||||
sb.append(0);
|
||||
sb.append(rem);
|
||||
}
|
||||
index += 2;
|
||||
}
|
||||
fi = f.intValue();
|
||||
}
|
||||
sb.reverse();
|
||||
if (fi != -1) sb.append(".").append(fi);
|
||||
while (sb.charAt(0) == '0') sb.deleteCharAt(0);
|
||||
if (sb.charAt(0) == '.') sb.insert(0, '0');
|
||||
return new QuaterImaginary(sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
double real2 = real == -0.0 ? 0.0 : real; // get rid of negative zero
|
||||
double imag2 = imag == -0.0 ? 0.0 : imag; // ditto
|
||||
String result = imag2 >= 0.0 ? String.format("%.0f + %.0fi", real2, imag2) : String.format("%.0f - %.0fi", real2, -imag2);
|
||||
result = result.replace(".0 ", " ").replace(".0i", "i").replace(" + 0i", "");
|
||||
if (result.startsWith("0 + ")) result = result.substring(4);
|
||||
if (result.startsWith("0 - ")) result = result.substring(4);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class QuaterImaginary {
|
||||
private static final Complex TWOI = new Complex(0.0, 2.0);
|
||||
private static final Complex INVTWOI = TWOI.inv();
|
||||
|
||||
private String b2i;
|
||||
|
||||
public QuaterImaginary(String b2i) {
|
||||
if (b2i.equals("") || !b2i.chars().allMatch(c -> "0123.".indexOf(c) > -1) || b2i.chars().filter(c -> c == '.').count() > 1) {
|
||||
throw new RuntimeException("Invalid Base 2i number");
|
||||
}
|
||||
this.b2i = b2i;
|
||||
}
|
||||
|
||||
public Complex toComplex() {
|
||||
int pointPos = b2i.indexOf(".");
|
||||
int posLen = pointPos != -1 ? pointPos : b2i.length();
|
||||
Complex sum = new Complex(0, 0);
|
||||
Complex prod = new Complex(1, 0);
|
||||
|
||||
for (int j = 0; j < posLen; ++j) {
|
||||
double k = b2i.charAt(posLen - 1 - j) - '0';
|
||||
if (k > 0.0) sum = sum.add(prod.times(k));
|
||||
prod = prod.times(TWOI);
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = INVTWOI;
|
||||
for (int j = posLen + 1; j < b2i.length(); ++j) {
|
||||
double k = b2i.charAt(j) - '0';
|
||||
if (k > 0.0) sum = sum.add(prod.times(k));
|
||||
prod = prod.times(INVTWOI);
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return b2i;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String fmt = "%4s -> %8s -> %4s";
|
||||
for (int i = 1; i <= 16; ++i) {
|
||||
Complex c1 = new Complex(i, 0);
|
||||
QuaterImaginary qi = c1.toQuaterImaginary();
|
||||
Complex c2 = qi.toComplex();
|
||||
System.out.printf(fmt + " ", c1, qi, c2);
|
||||
c1 = c2.unaryMinus();
|
||||
qi = c1.toQuaterImaginary();
|
||||
c2 = qi.toComplex();
|
||||
System.out.printf(fmt, c1, qi, c2);
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println();
|
||||
for (int i = 1; i <= 16; ++i) {
|
||||
Complex c1 = new Complex(0, i);
|
||||
QuaterImaginary qi = c1.toQuaterImaginary();
|
||||
Complex c2 = qi.toComplex();
|
||||
System.out.printf(fmt + " ", c1, qi, c2);
|
||||
c1 = c2.unaryMinus();
|
||||
qi = c1.toQuaterImaginary();
|
||||
c2 = qi.toComplex();
|
||||
System.out.printf(fmt, c1, qi, c2);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
168
Task/Imaginary-base-numbers/Julia/imaginary-base-numbers.julia
Normal file
168
Task/Imaginary-base-numbers/Julia/imaginary-base-numbers.julia
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
import Base.show, Base.parse, Base.+, Base.-, Base.*, Base./, Base.^
|
||||
|
||||
function inbase4(charvec::Vector)
|
||||
if (!all(x -> x in ['-', '0', '1', '2', '3', '.'], charvec)) ||
|
||||
((x = findlast(x -> x == '-', charvec)) != nothing && x > findfirst(x -> x != '-', charvec)) ||
|
||||
((x = findall(x -> x == '.', charvec)) != nothing && length(x) > 1)
|
||||
return false
|
||||
end
|
||||
true
|
||||
end
|
||||
inbase4(s::String) = inbase4(split(s, ""))
|
||||
|
||||
abstract type ImaginaryBaseNumber <: Number end
|
||||
|
||||
struct QuaterImaginary <: ImaginaryBaseNumber
|
||||
cvector::Vector{Char}
|
||||
isnegative::Bool
|
||||
end
|
||||
|
||||
function QuaterImaginary(charvec::Vector{Char})
|
||||
isneg = false
|
||||
if !inbase4(charvec)
|
||||
throw("Constructor vector for QuaterImaginary ($charvec) is not base 2i")
|
||||
elseif (i = length(findall(x -> x == '-', charvec))) > 0
|
||||
isneg = (-1) ^ i == -1
|
||||
end
|
||||
while length(charvec) > 1 && charvec[1] == '0' && charvec[2] != '.'
|
||||
popfirst!(charvec)
|
||||
end
|
||||
if (i = findfirst(x -> x == '.', charvec)) != nothing
|
||||
while length(charvec) > 3 && charvec[end] == '0' && charvec[end-1] != '.'
|
||||
pop!(charvec)
|
||||
end
|
||||
end
|
||||
if charvec[1] == '.'
|
||||
pushfirst!(charvec, '0')
|
||||
end
|
||||
if charvec[end] == '.'
|
||||
pop!(charvec)
|
||||
end
|
||||
QuaterImaginary(filter!(x -> x in ['0', '1', '2', '3', '.'], charvec), isneg)
|
||||
end
|
||||
|
||||
function QuaterImaginary(s::String = "0")
|
||||
if match(r"^-?[0123\.]+$", s) == nothing
|
||||
throw("String constructor argument <$s> for QuaterImaginary is not base 2i")
|
||||
end
|
||||
QuaterImaginary([s[i] for i in 1:length(s)])
|
||||
end
|
||||
|
||||
show(io::IO, qim::QuaterImaginary) = print(io, qim.isnegative ? "-" : "", join(qim.cvector, ""))
|
||||
|
||||
function parse(QuaterImaginary, x::Complex)
|
||||
sb = Vector{Char}()
|
||||
rea, ima = Int(floor(real(x))), Int(floor(imag(x)))
|
||||
if floor(real(x)) != rea || floor(imag(x)) != ima
|
||||
throw("Non-integer real and complex portions of complex numbers are not supported for QuaterImaginary")
|
||||
elseif rea == 0 == ima
|
||||
return QuaterImaginary(['0'])
|
||||
else
|
||||
fi = -1
|
||||
while rea != 0
|
||||
rea, rem = divrem(rea, -4)
|
||||
if rem < 0
|
||||
rem += 4
|
||||
rea += 1
|
||||
end
|
||||
push!(sb, Char(rem + '0'), '0')
|
||||
end
|
||||
if ima != 0
|
||||
f = real((ima * im)/(2im))
|
||||
ima = Int(ceil(f))
|
||||
f = -4.0 * (f - ima)
|
||||
idx = 1
|
||||
while ima != 0
|
||||
ima, rem = divrem(ima, -4)
|
||||
if rem < 0
|
||||
rem += 4
|
||||
ima += 1
|
||||
end
|
||||
if idx < length(sb)
|
||||
sb[idx + 1] = Char(rem + '0')
|
||||
else
|
||||
push!(sb, '0', Char(rem + '0'))
|
||||
end
|
||||
idx += 2
|
||||
end
|
||||
fi = Int(floor(f))
|
||||
end
|
||||
sb = reverse(sb)
|
||||
if fi != -1
|
||||
push!(sb, '.')
|
||||
append!(sb, map(x -> x[1], split(string(fi), "")))
|
||||
end
|
||||
end
|
||||
QuaterImaginary(sb)
|
||||
end
|
||||
|
||||
function parse(Complex, qim::QuaterImaginary)
|
||||
pointpos = ((x = indexin('.', qim.cvector))[1] == nothing) ? -1 : x[1]
|
||||
poslen = (pointpos != -1) ? pointpos : length(qim.cvector) + 1
|
||||
qsum = 0.0 + 0.0im
|
||||
prod = 1.0 + 0.0im
|
||||
for j in 1:poslen-1
|
||||
k = Float64(qim.cvector[poslen - j] - '0')
|
||||
if k > 0.0
|
||||
qsum += prod * k
|
||||
end
|
||||
prod *= 2im
|
||||
end
|
||||
if pointpos != -1
|
||||
prod = inv(2im)
|
||||
for j in poslen+1:length(qim.cvector)
|
||||
k = Float64(qim.cvector[j] - '0')
|
||||
if k > 0.0
|
||||
qsum += prod * k
|
||||
end
|
||||
prod *= inv(2im)
|
||||
end
|
||||
end
|
||||
qsum
|
||||
end
|
||||
|
||||
function testquim()
|
||||
function printcqc(c)
|
||||
q = parse(QuaterImaginary, Complex(c))
|
||||
c2 = parse(Complex, q)
|
||||
if imag(c2) == 0
|
||||
c2 = Int(c2)
|
||||
end
|
||||
print(lpad(c, 10), " -> ", lpad(q, 10), " -> ", lpad(c2, 12))
|
||||
end
|
||||
for i in 1:16
|
||||
printcqc(i)
|
||||
print(" ")
|
||||
printcqc(-i)
|
||||
println()
|
||||
end
|
||||
println()
|
||||
for i in 1:16
|
||||
c1 = Complex(0, i)
|
||||
printcqc(c1)
|
||||
print(" ")
|
||||
printcqc(-c1)
|
||||
println()
|
||||
end
|
||||
end
|
||||
|
||||
QuaterImaginary(c::Complex) = parse(QuaterImaginary, c)
|
||||
Complex(q::QuaterImaginary) = parse(Complex, q)
|
||||
|
||||
+(q1::QuaterImaginary, q2::QuaterImaginary) = QuaterImaginary(Complex(q1) + Complex(q2))
|
||||
+(q1::Complex, q2::QuaterImaginary) = q1 + Complex(q2)
|
||||
+(q1::QuaterImaginary, q2::Complex) = Complex(q1) + q2
|
||||
-(q1::QuaterImaginary, q2::QuaterImaginary) = QuaterImaginary(Complex(q1) - Complex(q2))
|
||||
-(q1::Complex, q2::QuaterImaginary) = q1 - Complex(q2)
|
||||
-(q1::QuaterImaginary, q2::Complex) = Complex(q1) - q2
|
||||
*(q1::QuaterImaginary, q2::QuaterImaginary) = QuaterImaginary(Complex(q1) * Complex(q2))
|
||||
*(q1::Complex, q2::QuaterImaginary) = q1 * Complex(q2)
|
||||
*(q1::QuaterImaginary, q2::Complex) = Complex(q1) * q2
|
||||
/(q1::QuaterImaginary, q2::QuaterImaginary) = QuaterImaginary(Complex(q1) / Complex(q2))
|
||||
/(q1::Complex, q2::QuaterImaginary) = q1 / Complex(q2)
|
||||
/(q1::QuaterImaginary, q2::Complex) = Complex(q1) / q2
|
||||
^(q1::QuaterImaginary, q2::QuaterImaginary) = QuaterImaginary(Complex(q1) ^ Complex(q2))
|
||||
^(q1::Complex, q2::QuaterImaginary) = q1 ^ Complex(q2)
|
||||
^(q1::QuaterImaginary, q2::Complex) = Complex(q1) ^ q2
|
||||
|
||||
testquim()
|
||||
146
Task/Imaginary-base-numbers/Kotlin/imaginary-base-numbers.kotlin
Normal file
146
Task/Imaginary-base-numbers/Kotlin/imaginary-base-numbers.kotlin
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
// version 1.2.10
|
||||
|
||||
import kotlin.math.ceil
|
||||
|
||||
class Complex(val real: Double, val imag: Double) {
|
||||
|
||||
constructor(r: Int, i: Int) : this(r.toDouble(), i.toDouble())
|
||||
|
||||
operator fun plus(other: Complex) = Complex(real + other.real, imag + other.imag)
|
||||
|
||||
operator fun times(other: Complex) = Complex(
|
||||
real * other.real - imag * other.imag,
|
||||
real * other.imag + imag * other.real
|
||||
)
|
||||
|
||||
operator fun times(other: Double) = Complex(real * other, imag * other)
|
||||
|
||||
fun inv(): Complex {
|
||||
val denom = real * real + imag * imag
|
||||
return Complex(real / denom, -imag / denom)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Complex(-real, -imag)
|
||||
|
||||
operator fun minus(other: Complex) = this + (-other)
|
||||
|
||||
operator fun div(other: Complex) = this * other.inv()
|
||||
|
||||
// only works properly if 'real' and 'imag' are both integral
|
||||
fun toQuaterImaginary(): QuaterImaginary {
|
||||
if (real == 0.0 && imag == 0.0) return QuaterImaginary("0")
|
||||
var re = real.toInt()
|
||||
var im = imag.toInt()
|
||||
var fi = -1
|
||||
val sb = StringBuilder()
|
||||
while (re != 0) {
|
||||
var rem = re % -4
|
||||
re /= -4
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem
|
||||
re++
|
||||
}
|
||||
sb.append(rem)
|
||||
sb.append(0)
|
||||
}
|
||||
if (im != 0) {
|
||||
var f = (Complex(0.0, imag) / Complex(0.0, 2.0)).real
|
||||
im = ceil(f).toInt()
|
||||
f = -4.0 * (f - im.toDouble())
|
||||
var index = 1
|
||||
while (im != 0) {
|
||||
var rem = im % -4
|
||||
im /= -4
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem
|
||||
im++
|
||||
}
|
||||
if (index < sb.length) {
|
||||
sb[index] = (rem + 48).toChar()
|
||||
}
|
||||
else {
|
||||
sb.append(0)
|
||||
sb.append(rem)
|
||||
}
|
||||
index += 2
|
||||
}
|
||||
fi = f.toInt()
|
||||
}
|
||||
sb.reverse()
|
||||
if (fi != -1) sb.append(".$fi")
|
||||
var s = sb.toString().trimStart('0')
|
||||
if (s.startsWith(".")) s = "0$s"
|
||||
return QuaterImaginary(s)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val real2 = if (real == -0.0) 0.0 else real // get rid of negative zero
|
||||
val imag2 = if (imag == -0.0) 0.0 else imag // ditto
|
||||
var result = if (imag2 >= 0.0) "$real2 + ${imag2}i" else "$real2 - ${-imag2}i"
|
||||
result = result.replace(".0 ", " ").replace(".0i", "i").replace(" + 0i", "")
|
||||
if (result.startsWith("0 + ")) result = result.drop(4)
|
||||
if (result.startsWith("0 - ")) result = "-" + result.drop(4)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class QuaterImaginary(val b2i: String) {
|
||||
|
||||
init {
|
||||
if (b2i == "" || !b2i.all { it in "0123." } || b2i.count { it == '.'} > 1 )
|
||||
throw RuntimeException("Invalid Base 2i number")
|
||||
}
|
||||
|
||||
fun toComplex(): Complex {
|
||||
val pointPos = b2i.indexOf(".")
|
||||
var posLen = if (pointPos != -1) pointPos else b2i.length
|
||||
var sum = Complex(0.0, 0.0)
|
||||
var prod = Complex(1.0, 0.0)
|
||||
for (j in 0 until posLen) {
|
||||
val k = (b2i[posLen - 1 - j] - '0').toDouble()
|
||||
if (k > 0.0) sum += prod * k
|
||||
prod *= twoI
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = invTwoI
|
||||
for (j in posLen + 1 until b2i.length) {
|
||||
val k = (b2i[j] - '0').toDouble()
|
||||
if (k > 0.0) sum += prod * k
|
||||
prod *= invTwoI
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
override fun toString() = b2i
|
||||
|
||||
companion object {
|
||||
val twoI = Complex(0.0, 2.0)
|
||||
val invTwoI = twoI.inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val fmt = "%4s -> %8s -> %4s"
|
||||
for (i in 1..16) {
|
||||
var c1 = Complex(i, 0)
|
||||
var qi = c1.toQuaterImaginary()
|
||||
var c2 = qi.toComplex()
|
||||
print("$fmt ".format(c1, qi, c2))
|
||||
c1 = -c1
|
||||
qi = c1.toQuaterImaginary()
|
||||
c2 = qi.toComplex()
|
||||
println(fmt.format(c1, qi, c2))
|
||||
}
|
||||
println()
|
||||
for (i in 1..16) {
|
||||
var c1 = Complex(0, i)
|
||||
var qi = c1.toQuaterImaginary()
|
||||
var c2 = qi.toComplex()
|
||||
print("$fmt ".format(c1, qi, c2))
|
||||
c1 = -c1
|
||||
qi = c1.toQuaterImaginary()
|
||||
c2 = qi.toComplex()
|
||||
println(fmt.format(c1, qi, c2))
|
||||
}
|
||||
}
|
||||
337
Task/Imaginary-base-numbers/Modula-2/imaginary-base-numbers.mod2
Normal file
337
Task/Imaginary-base-numbers/Modula-2/imaginary-base-numbers.mod2
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
MODULE ImaginaryBase;
|
||||
FROM FormatString IMPORT FormatString;
|
||||
FROM RealMath IMPORT round;
|
||||
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
|
||||
|
||||
(* Helper *)
|
||||
TYPE
|
||||
String = ARRAY[0..10] OF CHAR;
|
||||
StringBuilder = RECORD
|
||||
buf : String;
|
||||
ptr : CARDINAL;
|
||||
END;
|
||||
|
||||
PROCEDURE ToChar(n : INTEGER) : CHAR;
|
||||
BEGIN
|
||||
CASE n OF
|
||||
0 : RETURN '0' |
|
||||
1 : RETURN '1' |
|
||||
2 : RETURN '2' |
|
||||
3 : RETURN '3' |
|
||||
4 : RETURN '4' |
|
||||
5 : RETURN '5' |
|
||||
6 : RETURN '6' |
|
||||
7 : RETURN '7' |
|
||||
8 : RETURN '8' |
|
||||
9 : RETURN '9'
|
||||
ELSE
|
||||
RETURN '-'
|
||||
END
|
||||
END ToChar;
|
||||
|
||||
PROCEDURE AppendChar(VAR sb : StringBuilder; c : CHAR);
|
||||
BEGIN
|
||||
sb.buf[sb.ptr] := c;
|
||||
INC(sb.ptr);
|
||||
sb.buf[sb.ptr] := 0C
|
||||
END AppendChar;
|
||||
|
||||
PROCEDURE AppendInt(VAR sb : StringBuilder; n : INTEGER);
|
||||
BEGIN
|
||||
sb.buf[sb.ptr] := ToChar(n);
|
||||
INC(sb.ptr);
|
||||
sb.buf[sb.ptr] := 0C
|
||||
END AppendInt;
|
||||
|
||||
PROCEDURE Ceil(r : REAL) : REAL;
|
||||
VAR t : REAL;
|
||||
BEGIN
|
||||
t := FLOAT(INT(r));
|
||||
IF r - t > 0.0 THEN
|
||||
t := t + 1.0
|
||||
END;
|
||||
RETURN t
|
||||
END Ceil;
|
||||
|
||||
PROCEDURE Modulus(q,d : INTEGER) : INTEGER;
|
||||
VAR t : INTEGER;
|
||||
BEGIN
|
||||
t := q / d;
|
||||
RETURN q - d * t
|
||||
END Modulus;
|
||||
|
||||
PROCEDURE PrependInt(VAR sb : StringBuilder; n : INTEGER);
|
||||
VAR i : CARDINAL;
|
||||
BEGIN
|
||||
i := sb.ptr;
|
||||
INC(sb.ptr);
|
||||
sb.buf[sb.ptr] := 0C;
|
||||
WHILE i > 0 DO
|
||||
sb.buf[i] := sb.buf[i-1];
|
||||
DEC(i)
|
||||
END;
|
||||
sb.buf[0] := ToChar(n)
|
||||
END PrependInt;
|
||||
|
||||
PROCEDURE Reverse(VAR str : String);
|
||||
VAR
|
||||
i,j : CARDINAL;
|
||||
c : CHAR;
|
||||
BEGIN
|
||||
IF str[0] = 0C THEN RETURN END;
|
||||
i := 0;
|
||||
WHILE str[i] # 0C DO INC(i) END;
|
||||
DEC(i);
|
||||
j := 0;
|
||||
WHILE i > j DO
|
||||
c := str[i];
|
||||
str[i] := str[j];
|
||||
str[j] := c;
|
||||
|
||||
DEC(i);
|
||||
INC(j)
|
||||
END
|
||||
END Reverse;
|
||||
|
||||
PROCEDURE TrimStart(VAR str : String; c : CHAR);
|
||||
VAR i : CARDINAL;
|
||||
BEGIN
|
||||
WHILE str[0] = c DO
|
||||
i := 0;
|
||||
WHILE str[i] # 0C DO
|
||||
str[i] := str[i+1];
|
||||
INC(i)
|
||||
END
|
||||
END
|
||||
END TrimStart;
|
||||
|
||||
PROCEDURE WriteInteger(n : INTEGER);
|
||||
VAR buf : ARRAY[0..15] OF CHAR;
|
||||
BEGIN
|
||||
FormatString("%i", buf, n);
|
||||
WriteString(buf)
|
||||
END WriteInteger;
|
||||
|
||||
(* Imaginary *)
|
||||
TYPE
|
||||
Complex = RECORD
|
||||
real,imag : REAL;
|
||||
END;
|
||||
QuaterImaginary = RECORD
|
||||
b2i : String;
|
||||
END;
|
||||
|
||||
PROCEDURE ComplexMul(lhs,rhs : Complex) : Complex;
|
||||
BEGIN
|
||||
RETURN Complex{
|
||||
rhs.real * lhs.real - rhs.imag * lhs.imag,
|
||||
rhs.real * lhs.imag + rhs.imag * lhs.real
|
||||
}
|
||||
END ComplexMul;
|
||||
|
||||
PROCEDURE ComplexMulR(lhs : Complex; rhs : REAL) : Complex;
|
||||
BEGIN
|
||||
RETURN Complex{lhs.real * rhs, lhs.imag * rhs}
|
||||
END ComplexMulR;
|
||||
|
||||
PROCEDURE ComplexInv(c : Complex) : Complex;
|
||||
VAR denom : REAL;
|
||||
BEGIN
|
||||
denom := c.real * c.real + c.imag * c.imag;
|
||||
RETURN Complex{c.real / denom, -c.imag / denom}
|
||||
END ComplexInv;
|
||||
|
||||
PROCEDURE ComplexDiv(lhs,rhs : Complex) : Complex;
|
||||
BEGIN
|
||||
RETURN ComplexMul(lhs, ComplexInv(rhs))
|
||||
END ComplexDiv;
|
||||
|
||||
PROCEDURE ComplexNeg(c : Complex) : Complex;
|
||||
BEGIN
|
||||
RETURN Complex{-c.real, -c.imag}
|
||||
END ComplexNeg;
|
||||
|
||||
PROCEDURE ComplexSum(lhs,rhs : Complex) : Complex;
|
||||
BEGIN
|
||||
RETURN Complex{lhs.real + rhs.real, lhs.imag + rhs.imag}
|
||||
END ComplexSum;
|
||||
|
||||
PROCEDURE WriteComplex(c : Complex);
|
||||
VAR buf : ARRAY[0..15] OF CHAR;
|
||||
BEGIN
|
||||
IF c.imag = 0.0 THEN
|
||||
WriteInteger(INT(c.real))
|
||||
ELSIF c.real = 0.0 THEN
|
||||
WriteInteger(INT(c.imag));
|
||||
WriteString("i")
|
||||
ELSIF c.imag > 0.0 THEN
|
||||
WriteInteger(INT(c.real));
|
||||
WriteString(" + ");
|
||||
WriteInteger(INT(c.imag));
|
||||
WriteString("i")
|
||||
ELSE
|
||||
WriteInteger(INT(c.real));
|
||||
WriteString(" - ");
|
||||
WriteInteger(INT(-c.imag));
|
||||
WriteString("i")
|
||||
END
|
||||
END WriteComplex;
|
||||
|
||||
PROCEDURE ToQuaterImaginary(c : Complex) : QuaterImaginary;
|
||||
VAR
|
||||
re,im,fi,rem,index : INTEGER;
|
||||
f : REAL;
|
||||
t : Complex;
|
||||
sb : StringBuilder;
|
||||
BEGIN
|
||||
IF (c.real = 0.0) AND (c.imag = 0.0) THEN RETURN QuaterImaginary{"0"} END;
|
||||
re := INT(c.real);
|
||||
im := INT(c.imag);
|
||||
fi := -1;
|
||||
sb := StringBuilder{"", 0};
|
||||
WHILE re # 0 DO
|
||||
rem := Modulus(re, -4);
|
||||
re := re / (-4);
|
||||
IF rem < 0 THEN
|
||||
rem := 4 + rem;
|
||||
INC(re)
|
||||
END;
|
||||
AppendInt(sb, rem);
|
||||
AppendInt(sb, 0)
|
||||
END;
|
||||
IF im # 0 THEN
|
||||
t := ComplexDiv(Complex{0.0, c.imag}, Complex{0.0, 2.0});
|
||||
f := t.real;
|
||||
im := INT(Ceil(f));
|
||||
f := -4.0 * (f - FLOAT(im));
|
||||
index := 1;
|
||||
WHILE im # 0 DO
|
||||
rem := Modulus(im, -4);
|
||||
im := im / (-4);
|
||||
IF rem < 0 THEN
|
||||
rem := 4 + rem;
|
||||
INC(im)
|
||||
END;
|
||||
IF index < INT(sb.ptr) THEN
|
||||
sb.buf[index] := ToChar(rem)
|
||||
ELSE
|
||||
AppendInt(sb, 0);
|
||||
AppendInt(sb, rem)
|
||||
END;
|
||||
index := index + 2;
|
||||
END;
|
||||
fi := INT(f)
|
||||
END;
|
||||
Reverse(sb.buf);
|
||||
IF fi # -1 THEN
|
||||
AppendChar(sb, '.');
|
||||
AppendInt(sb, fi)
|
||||
END;
|
||||
TrimStart(sb.buf, '0');
|
||||
IF sb.buf[0] = '.' THEN
|
||||
PrependInt(sb, 0)
|
||||
END;
|
||||
|
||||
RETURN QuaterImaginary{sb.buf}
|
||||
END ToQuaterImaginary;
|
||||
|
||||
PROCEDURE ToComplex(qi : QuaterImaginary) : Complex;
|
||||
VAR
|
||||
j,pointPos,posLen,b2iLen : INTEGER;
|
||||
k : REAL;
|
||||
sum,prod : Complex;
|
||||
BEGIN
|
||||
pointPos := 0;
|
||||
WHILE (qi.b2i[pointPos] # 0C) AND (qi.b2i[pointPos] # '.') DO
|
||||
INC(pointPos)
|
||||
END;
|
||||
IF qi.b2i[pointPos] # '.' THEN
|
||||
pointPos := -1;
|
||||
posLen := 0;
|
||||
WHILE qi.b2i[posLen] # 0C DO
|
||||
INC(posLen)
|
||||
END
|
||||
ELSE
|
||||
posLen := pointPos
|
||||
END;
|
||||
|
||||
sum := Complex{0.0, 0.0};
|
||||
prod := Complex{1.0, 0.0};
|
||||
|
||||
FOR j:=0 TO posLen - 1 DO
|
||||
k := FLOAT(ORD(qi.b2i[posLen - 1 - j]) - ORD('0'));
|
||||
IF k > 0.0 THEN
|
||||
sum := ComplexSum(sum, ComplexMulR(prod, k))
|
||||
END;
|
||||
prod := ComplexMul(prod, Complex{0.0, 2.0})
|
||||
END;
|
||||
|
||||
IF pointPos # -1 THEN
|
||||
prod := ComplexInv(Complex{0.0, 2.0});
|
||||
b2iLen := 0;
|
||||
WHILE qi.b2i[b2iLen] # 0C DO INC(b2iLen) END;
|
||||
FOR j:=posLen + 1 TO b2iLen - 1 DO
|
||||
k := FLOAT(ORD(qi.b2i[j]) - ORD('0'));
|
||||
IF k > 0.0 THEN
|
||||
sum := ComplexSum(sum, ComplexMulR(prod, k))
|
||||
END;
|
||||
prod := ComplexMul(prod, ComplexInv(Complex{0.0, 2.0}))
|
||||
END
|
||||
END;
|
||||
|
||||
RETURN sum
|
||||
END ToComplex;
|
||||
|
||||
(* Main *)
|
||||
VAR
|
||||
c1,c2 : Complex;
|
||||
qi : QuaterImaginary;
|
||||
i : INTEGER;
|
||||
BEGIN
|
||||
FOR i:=1 TO 16 DO
|
||||
c1 := Complex{FLOAT(i), 0.0};
|
||||
WriteComplex(c1);
|
||||
WriteString(" -> ");
|
||||
qi := ToQuaterImaginary(c1);
|
||||
WriteString(qi.b2i);
|
||||
WriteString(" -> ");
|
||||
c2 := ToComplex(qi);
|
||||
WriteComplex(c2);
|
||||
WriteString(" ");
|
||||
|
||||
c1 := ComplexNeg(c1);
|
||||
WriteComplex(c1);
|
||||
WriteString(" -> ");
|
||||
qi := ToQuaterImaginary(c1);
|
||||
WriteString(qi.b2i);
|
||||
WriteString(" -> ");
|
||||
c2 := ToComplex(qi);
|
||||
WriteComplex(c2);
|
||||
WriteLn
|
||||
END;
|
||||
WriteLn;
|
||||
|
||||
FOR i:=1 TO 16 DO
|
||||
c1 := Complex{0.0, FLOAT(i)};
|
||||
WriteComplex(c1);
|
||||
WriteString(" -> ");
|
||||
qi := ToQuaterImaginary(c1);
|
||||
WriteString(qi.b2i);
|
||||
WriteString(" -> ");
|
||||
c2 := ToComplex(qi);
|
||||
WriteComplex(c2);
|
||||
WriteString(" ");
|
||||
|
||||
c1 := ComplexNeg(c1);
|
||||
WriteComplex(c1);
|
||||
WriteString(" -> ");
|
||||
qi := ToQuaterImaginary(c1);
|
||||
WriteString(qi.b2i);
|
||||
WriteString(" -> ");
|
||||
c2 := ToComplex(qi);
|
||||
WriteComplex(c2);
|
||||
WriteLn
|
||||
END;
|
||||
|
||||
ReadChar
|
||||
END ImaginaryBase.
|
||||
135
Task/Imaginary-base-numbers/Nim/imaginary-base-numbers.nim
Normal file
135
Task/Imaginary-base-numbers/Nim/imaginary-base-numbers.nim
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
import algorithm, complex, math, strformat, strutils
|
||||
|
||||
const
|
||||
TwoI = complex(0.0, 2.0)
|
||||
InvTwoI = inv(TwoI)
|
||||
|
||||
type QuaterImaginery = object
|
||||
b2i: string
|
||||
|
||||
# Conversions between digit character and digit value.
|
||||
template digitChar(n: range[0..9]): range['0'..'9'] = chr(n + ord('0'))
|
||||
template digitValue(c: range['0'..'9']): range[0..9] = ord(c) - ord('0')
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Quater imaginary functions.
|
||||
|
||||
func initQuaterImaginary(s: string): QuaterImaginery =
|
||||
## Create a Quater imaginary number.
|
||||
if s.len == 0 or not s.allCharsInSet({'0'..'3', '.'}) or s.count('.') > 1:
|
||||
raise newException(ValueError, "invalid base 2i number.")
|
||||
result = QuaterImaginery(b2i: s)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func toComplex(q: QuaterImaginery): Complex[float] =
|
||||
## Convert a Quater imaginary number to a complex.
|
||||
|
||||
let pointPos = q.b2i.find('.')
|
||||
let posLen = if pointPos != -1: pointPos else: q.b2i.len
|
||||
var prod = complex(1.0)
|
||||
|
||||
for j in 0..<posLen:
|
||||
let k = float(q.b2i[posLen - 1 - j].digitValue)
|
||||
if k > 0: result += prod * k
|
||||
prod *= TwoI
|
||||
|
||||
if pointPos != -1:
|
||||
prod = InvTwoI
|
||||
for j in (posLen + 1)..q.b2i.high:
|
||||
let k = float(q.b2i[j].digitValue)
|
||||
if k > 0: result += prod * k
|
||||
prod *= InvTwoI
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func `$`(q: QuaterImaginery): string =
|
||||
## Convert a Quater imaginary number to a string.
|
||||
q.b2i
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Supplementary functions for complex numbers.
|
||||
|
||||
func toQuaterImaginary(c: Complex): QuaterImaginery =
|
||||
## Convert a complex number to a Quater imaginary number.
|
||||
|
||||
if c.re == 0 and c.im == 0: return initQuaterImaginary("0")
|
||||
|
||||
var re = c.re.toInt
|
||||
var im = c.im.toInt
|
||||
var fi = -1
|
||||
|
||||
while re != 0:
|
||||
var rem = re mod -4
|
||||
re = re div -4
|
||||
if rem < 0:
|
||||
inc rem, 4
|
||||
inc re
|
||||
result.b2i.add rem.digitChar
|
||||
result.b2i.add '0'
|
||||
|
||||
if im != 0:
|
||||
var f = (complex(0.0, c.im) / TwoI).re
|
||||
im = f.ceil.toInt
|
||||
f = -4 * (f - im.toFloat)
|
||||
var index = 1
|
||||
while im != 0:
|
||||
var rem = im mod -4
|
||||
im = im div -4
|
||||
if rem < 0:
|
||||
inc rem, 4
|
||||
inc im
|
||||
if index < result.b2i.len:
|
||||
result.b2i[index] = rem.digitChar
|
||||
else:
|
||||
result.b2i.add '0'
|
||||
result.b2i.add rem.digitChar
|
||||
inc index, 2
|
||||
fi = f.toInt
|
||||
|
||||
result.b2i.reverse()
|
||||
if fi != -1: result.b2i.add "." & $fi
|
||||
result.b2i = result.b2i.strip(leading = true, trailing = false, {'0'})
|
||||
if result.b2i.startsWith('.'): result.b2i = '0' & result.b2i
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func toString(c: Complex[float]): string =
|
||||
## Convert a complex number to a string.
|
||||
## This function is used in place of `$`.
|
||||
|
||||
let real = if c.re.classify == fcNegZero: 0.0 else: c.re
|
||||
let imag = if c.im.classify == fcNegZero: 0.0 else: c.im
|
||||
result = if imag >= 0: fmt"{real} + {imag}i" else: fmt"{real} - {-imag}i"
|
||||
result = result.replace(".0 ", " ").replace(".0i", "i").replace(" + 0i", "")
|
||||
if result.startsWith("0 + "): result = result[4..^1]
|
||||
if result.startsWith("0 - "): result = '-' & result[4..^1]
|
||||
|
||||
|
||||
#———————————————————————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
when isMainModule:
|
||||
|
||||
for i in 1..16:
|
||||
var c1 = complex(i.toFloat)
|
||||
var qi = c1.toQuaterImaginary
|
||||
var c2 = qi.toComplex
|
||||
stdout.write fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s} "
|
||||
c1 = -c1
|
||||
qi = c1.toQuaterImaginary
|
||||
c2 = qi.toComplex
|
||||
echo fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s}"
|
||||
|
||||
echo ""
|
||||
|
||||
for i in 1..16:
|
||||
var c1 = complex(0.0, i.toFloat)
|
||||
var qi = c1.toQuaterImaginary
|
||||
var c2 = qi.toComplex
|
||||
stdout.write fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s} "
|
||||
c1 = -c1
|
||||
qi = c1.toQuaterImaginary
|
||||
c2 = qi.toComplex
|
||||
echo fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s}"
|
||||
82
Task/Imaginary-base-numbers/Perl/imaginary-base-numbers.pl
Normal file
82
Task/Imaginary-base-numbers/Perl/imaginary-base-numbers.pl
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
|
||||
use Math::Complex;
|
||||
use List::AllUtils qw(sum mesh);
|
||||
use ntheory qw<todigitstring fromdigits>;
|
||||
|
||||
sub zip {
|
||||
my($a,$b) = @_;
|
||||
my($la, $lb) = (length $a, length $b);
|
||||
my $l = '0' x abs $la - $lb;
|
||||
$a .= $l if $la < $lb;
|
||||
$b .= $l if $lb < $la;
|
||||
(join('', mesh(@{[split('',$a),]}, @{[split('',$b),]})) =~ s/0+$//r) or 0;
|
||||
}
|
||||
|
||||
sub base_i {
|
||||
my($num,$radix,$precision) = @_;
|
||||
die unless $radix > -37 and $radix < -1;
|
||||
return '0' unless $num;
|
||||
my $value = $num;
|
||||
my $result = '';
|
||||
my $place = 0;
|
||||
my $upper_bound = 1 / (-$radix + 1);
|
||||
my $lower_bound = $radix * $upper_bound;
|
||||
|
||||
$value = $num / $radix ** ++$place until $lower_bound <= $value and $value < $upper_bound;
|
||||
|
||||
while (($value or $place > 0) and $place > $precision) {
|
||||
my $digit = int $radix * $value - $lower_bound;
|
||||
$value = $radix * $value - $digit;
|
||||
$result .= '.' unless $place or not index($result, '.');
|
||||
$result .= $digit == -$radix ? todigitstring($digit-1, -$radix) . '0' : (todigitstring($digit, -$radix) or '0');
|
||||
$place--;
|
||||
}
|
||||
$result
|
||||
}
|
||||
|
||||
sub base_c {
|
||||
my($num, $radix, $precision) = @_;
|
||||
die "Base $radix out of range" unless
|
||||
(-6 <= $radix->Im or $radix->Im <= -2) or (2 <= $radix->Im or $radix->Im <= 6);
|
||||
my ($re,$im);
|
||||
defined $num->Im ? ($re, $im) = ($num->Re, $num->Im) : $re = $num;
|
||||
my ($re_wh, $re_fr) = split /\./, base_i( $re, -1 * int($radix->Im**2), $precision);
|
||||
my ($im_wh, $im_fr) = split /\./, base_i( ($im/($radix->Im)), -1 * int($radix->Im**2), $precision);
|
||||
$_ //= '' for $re_fr, $im_fr;
|
||||
|
||||
my $whole = reverse zip scalar reverse($re_wh), scalar reverse($im_wh);
|
||||
my $fraction = zip $im_fr, $re_fr;
|
||||
$fraction eq 0 ? "$whole" : "$whole.$fraction"
|
||||
}
|
||||
|
||||
sub parse_base {
|
||||
my($str, $radix) = @_;
|
||||
return -1 * parse_base( substr($str,1), $radix) if substr($str,0,1) eq '-';
|
||||
my($whole, $frac) = split /\./, $str;
|
||||
my $fraction = 0;
|
||||
my $k = 0;
|
||||
$fraction = sum map { (fromdigits($_, int $radix->Im**2) || 0) * $radix ** -($k++ +1) } split '', $frac
|
||||
if $frac;
|
||||
$k = 0;
|
||||
$fraction + sum map { (fromdigits($_, int $radix->Im**2) || 0) * $radix ** $k++ } reverse split '', $whole;
|
||||
}
|
||||
|
||||
for (
|
||||
[ 0*i, 2*i], [1+0*i, 2*i], [5+0*i, 2*i], [ -13+0*i, 2*i],
|
||||
[ 9*i, 2*i], [ -3*i, 2*i], [7.75-7.5*i, 2*i], [0.25+0*i, 2*i],
|
||||
[5+5*i, 2*i], [5+5*i, 3*i], [5+5*i, 4*i], [5+5*i, 5*i], [5+5*i, 6*i],
|
||||
[5+5*i, -2*i], [5+5*i, -3*i], [5+5*i, -4*i], [5+5*i, -5*i], [5+5*i, -6*i]
|
||||
) {
|
||||
my($v,$r) = @$_;
|
||||
my $ibase = base_c($v, $r, -6);
|
||||
my $rt = cplx parse_base($ibase, $r);
|
||||
$rt->display_format('format' => '%.2f');
|
||||
printf "base(%3s): %10s => %9s => %13s\n", $r, $v, $ibase, $rt;
|
||||
}
|
||||
|
||||
say '';
|
||||
say 'base( 6i): 31432.6219135802-2898.5266203704*i => ' .
|
||||
base_c(31432.6219135802-2898.5266203704*i, 0+6*i, -3);
|
||||
130
Task/Imaginary-base-numbers/Phix/imaginary-base-numbers.phix
Normal file
130
Task/Imaginary-base-numbers/Phix/imaginary-base-numbers.phix
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #004080;">complex</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">base2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">radix</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">precision</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">radix</span><span style="color: #0000FF;"><-</span><span style="color: #000000;">36</span> <span style="color: #008080;">or</span> <span style="color: #000000;">radix</span><span style="color: #0000FF;">>-</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #008080;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"radix out of range (-2..-36)"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">result</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">place</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">num</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">upper_bound</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">/(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">lower_bound</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">radix</span><span style="color: #0000FF;">*</span><span style="color: #000000;">upper_bound</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lower_bound</span> <span style="color: #0000FF;"><=</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #008080;">not</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">upper_bound</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">place</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">,</span><span style="color: #000000;">place</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
|
||||
<span style="color: #008080;">while</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">v</span> <span style="color: #008080;">or</span> <span style="color: #000000;">place</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">place</span> <span style="color: #0000FF;">></span> <span style="color: #000000;">precision</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">*</span><span style="color: #000000;">v</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">lower_bound</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">*</span><span style="color: #000000;">v</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">place</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">result</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'.'</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">+</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">></span><span style="color: #000000;">9</span><span style="color: #0000FF;">?</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">:</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">place</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">dot</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">result</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">dot</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">result</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">dot</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">result</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dot</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]}</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">zip</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ld</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">ld</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">ld</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">b</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ld</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">a</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ld</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">complexn</span> <span style="color: #000000;">num</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">radix</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">precision</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">absrad</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">radix2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">absrad</span><span style="color: #0000FF;"><</span><span style="color: #000000;">2</span> <span style="color: #008080;">or</span> <span style="color: #000000;">absrad</span><span style="color: #0000FF;">></span><span style="color: #000000;">6</span> <span style="color: #008080;">then</span> <span style="color: #008080;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"base radix out of range"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
|
||||
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">re</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">im</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">complex_real</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">),</span> <span style="color: #7060A8;">complex_imag</span><span style="color: #0000FF;">(</span><span style="color: #000000;">num</span><span style="color: #0000FF;">)}</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">re_wh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">re_fr</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">re</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">radix2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">precision</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">im_wh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">im_fr</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">im</span><span style="color: #0000FF;">/</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">radix2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">precision</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">whole</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">zip</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">re_wh</span><span style="color: #0000FF;">),</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">im_wh</span><span style="color: #0000FF;">))),</span>
|
||||
<span style="color: #000000;">fraction</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">zip</span><span style="color: #0000FF;">(</span><span style="color: #000000;">im_fr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">re_fr</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">fraction</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">"0"</span> <span style="color: #008080;">then</span> <span style="color: #000000;">whole</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'.'</span><span style="color: #0000FF;">&</span><span style="color: #000000;">fraction</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">whole</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">parse_base</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">str</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">radix</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #000000;">complexn</span> <span style="color: #000000;">fraction</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">dot</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">str</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">dot</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">fr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">str</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dot</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">-=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">?</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">:</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">fraction</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fraction</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">complex_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">complex_power</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">},-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">str</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">str</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">dot</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
|
||||
<span style="color: #000000;">str</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">str</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">str</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">c</span> <span style="color: #0000FF;">-=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">?</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">:</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">fraction</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fraction</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">complex_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">complex_power</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">radix</span><span style="color: #0000FF;">},(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">fraction</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">},</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">7.75</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">7.5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">},{.</span><span style="color: #000000;">25</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- base 2i tests</span>
|
||||
<span style="color: #0000FF;">{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- same value, positive imaginary bases</span>
|
||||
<span style="color: #0000FF;">{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},-</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},-</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- same value, negative imaginary bases</span>
|
||||
<span style="color: #0000FF;">{{</span><span style="color: #000000;">227.65625</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10.859375</span><span style="color: #0000FF;">},</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},</span> <span style="color: #000080;font-style:italic;">-- larger test value</span>
|
||||
<span style="color: #0000FF;">{{-</span><span style="color: #000000;">579.8225308641975744</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">5296.406378600824</span><span style="color: #0000FF;">},</span><span style="color: #000000;">6</span><span style="color: #0000FF;">}}</span> <span style="color: #000080;font-style:italic;">-- phix.rules
|
||||
|
||||
-- matches output of Sidef and Raku:</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">complexn</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">ibase</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">strv</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">strb</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">parse_base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ibase</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"base(%20s, %2di) = %-10s : parse_base(%12s, %2di) = %s\n"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">strv</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ibase</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">'"'</span><span style="color: #0000FF;">&</span><span style="color: #000000;">ibase</span><span style="color: #0000FF;">&</span><span style="color: #008000;">'"'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">strb</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- matches output of Kotlin, Java, Go, D, and C#:</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">ri</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- real then imag</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">16</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">complexn</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #000000;">i</span><span style="color: #0000FF;">:{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">}),</span>
|
||||
<span style="color: #000000;">nc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_neg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">sc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">snc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nc</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">ib</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">inb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">rc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">parse_base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ib</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)),</span>
|
||||
<span style="color: #000000;">rnc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">complex_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">parse_base</span><span style="color: #0000FF;">(</span><span style="color: #000000;">inb</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4s -> %8s -> %4s %4s -> %8s -> %4s\n"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">sc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ib</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">snc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">inb</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rnc</span> <span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
100
Task/Imaginary-base-numbers/Python/imaginary-base-numbers.py
Normal file
100
Task/Imaginary-base-numbers/Python/imaginary-base-numbers.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import math
|
||||
import re
|
||||
|
||||
def inv(c):
|
||||
denom = c.real * c.real + c.imag * c.imag
|
||||
return complex(c.real / denom, -c.imag / denom)
|
||||
|
||||
class QuaterImaginary:
|
||||
twoI = complex(0, 2)
|
||||
invTwoI = inv(twoI)
|
||||
|
||||
def __init__(self, str):
|
||||
if not re.match("^[0123.]+$", str) or str.count('.') > 1:
|
||||
raise Exception('Invalid base 2i number')
|
||||
self.b2i = str
|
||||
|
||||
def toComplex(self):
|
||||
pointPos = self.b2i.find('.')
|
||||
posLen = len(self.b2i) if (pointPos < 0) else pointPos
|
||||
sum = complex(0, 0)
|
||||
prod = complex(1, 0)
|
||||
for j in xrange(0, posLen):
|
||||
k = int(self.b2i[posLen - 1 - j])
|
||||
if k > 0:
|
||||
sum += prod * k
|
||||
prod *= QuaterImaginary.twoI
|
||||
if pointPos != -1:
|
||||
prod = QuaterImaginary.invTwoI
|
||||
for j in xrange(posLen + 1, len(self.b2i)):
|
||||
k = int(self.b2i[j])
|
||||
if k > 0:
|
||||
sum += prod * k
|
||||
prod *= QuaterImaginary.invTwoI
|
||||
return sum
|
||||
|
||||
def __str__(self):
|
||||
return str(self.b2i)
|
||||
|
||||
def toQuaterImaginary(c):
|
||||
if c.real == 0.0 and c.imag == 0.0:
|
||||
return QuaterImaginary("0")
|
||||
|
||||
re = int(c.real)
|
||||
im = int(c.imag)
|
||||
fi = -1
|
||||
ss = ""
|
||||
while re != 0:
|
||||
re, rem = divmod(re, -4)
|
||||
if rem < 0:
|
||||
rem += 4
|
||||
re += 1
|
||||
ss += str(rem) + '0'
|
||||
if im != 0:
|
||||
f = c.imag / 2
|
||||
im = int(math.ceil(f))
|
||||
f = -4 * (f - im)
|
||||
index = 1
|
||||
while im != 0:
|
||||
im, rem = divmod(im, -4)
|
||||
if rem < 0:
|
||||
rem += 4
|
||||
im += 1
|
||||
if index < len(ss):
|
||||
ss[index] = str(rem)
|
||||
else:
|
||||
ss += '0' + str(rem)
|
||||
index = index + 2
|
||||
fi = int(f)
|
||||
ss = ss[::-1]
|
||||
if fi != -1:
|
||||
ss += '.' + str(fi)
|
||||
ss = ss.lstrip('0')
|
||||
if ss[0] == '.':
|
||||
ss = '0' + ss
|
||||
return QuaterImaginary(ss)
|
||||
|
||||
for i in xrange(1,17):
|
||||
c1 = complex(i, 0)
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = qi.toComplex()
|
||||
print "{0:8} -> {1:>8} -> {2:8} ".format(c1, qi, c2),
|
||||
|
||||
c1 = -c1
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = qi.toComplex()
|
||||
print "{0:8} -> {1:>8} -> {2:8}".format(c1, qi, c2)
|
||||
print
|
||||
|
||||
for i in xrange(1,17):
|
||||
c1 = complex(0, i)
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = qi.toComplex()
|
||||
print "{0:8} -> {1:>8} -> {2:8} ".format(c1, qi, c2),
|
||||
|
||||
c1 = -c1
|
||||
qi = toQuaterImaginary(c1)
|
||||
c2 = qi.toComplex()
|
||||
print "{0:8} -> {1:>8} -> {2:8}".format(c1, qi, c2)
|
||||
|
||||
print "done"
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
multi sub base ( Real $num, Int $radix where -37 < * < -1, :$precision = -15 ) {
|
||||
return '0' unless $num;
|
||||
my $value = $num;
|
||||
my $result = '';
|
||||
my $place = 0;
|
||||
my $upper-bound = 1 / (-$radix + 1);
|
||||
my $lower-bound = $radix * $upper-bound;
|
||||
|
||||
$value = $num / $radix ** ++$place until $lower-bound <= $value < $upper-bound;
|
||||
|
||||
while ($value or $place > 0) and $place > $precision {
|
||||
my $digit = ($radix * $value - $lower-bound).Int;
|
||||
$value = $radix * $value - $digit;
|
||||
$result ~= '.' unless $place or $result.contains: '.';
|
||||
$result ~= $digit == -$radix ?? ($digit-1).base(-$radix)~'0' !! $digit.base(-$radix);
|
||||
$place--
|
||||
}
|
||||
$result
|
||||
}
|
||||
|
||||
multi sub base (Numeric $num, Complex $radix where *.re == 0, :$precision = -8 ) {
|
||||
die "Base $radix out of range" unless -6 <= $radix.im <= -2 or 2 <= $radix.im <= 6;
|
||||
my ($re, $im) = $num.Complex.reals;
|
||||
my ($re-wh, $re-fr) = $re.&base( -$radix.im².Int, :precision($precision) ).split: '.';
|
||||
my ($im-wh, $im-fr) = ($im/$radix.im).&base( -$radix.im².Int, :precision($precision) ).split: '.';
|
||||
$_ //= '' for $re-fr, $im-fr;
|
||||
|
||||
sub zip (Str $a, Str $b) {
|
||||
my $l = '0' x ($a.chars - $b.chars).abs;
|
||||
([~] flat ($a~$l).comb Z flat ($b~$l).comb).subst(/ '0'+ $ /, '') || '0'
|
||||
}
|
||||
|
||||
my $whole = flip zip $re-wh.flip, $im-wh.flip;
|
||||
my $fraction = zip $im-fr, $re-fr;
|
||||
$fraction eq 0 ?? "$whole" !! "$whole.$fraction"
|
||||
}
|
||||
|
||||
multi sub parse-base (Str $str, Complex $radix where *.re == 0) {
|
||||
return -1 * $str.substr(1).&parse-base($radix) if $str.substr(0,1) eq '-';
|
||||
my ($whole, $frac) = $str.split: '.';
|
||||
my $fraction = 0;
|
||||
$fraction = [+] $frac.comb.kv.map: { $^v.parse-base($radix.im².Int) * $radix ** -($^k+1) } if $frac;
|
||||
$fraction + [+] $whole.flip.comb.kv.map: { $^v.parse-base($radix.im².Int) * $radix ** $^k }
|
||||
}
|
||||
|
||||
# TESTING
|
||||
for 0, 2i, 1, 2i, 5, 2i, -13, 2i, 9i, 2i, -3i, 2i, 7.75-7.5i, 2i, .25, 2i, # base 2i tests
|
||||
5+5i, 2i, 5+5i, 3i, 5+5i, 4i, 5+5i, 5i, 5+5i, 6i, # same value, positive imaginary bases
|
||||
5+5i, -2i, 5+5i, -3i, 5+5i, -4i, 5+5i, -5i, 5+5i, -6i, # same value, negative imaginary bases
|
||||
227.65625+10.859375i, 4i, # larger test value
|
||||
31433.3487654321-2902.4480452675i, 6i # heh
|
||||
-> $v, $r {
|
||||
my $ibase = $v.&base($r, :precision(-6));
|
||||
printf "%33s.&base\(%2si\) = %-11s : %13s.&parse-base\(%2si\) = %s\n",
|
||||
$v, $r.im, $ibase, "'$ibase'", $r.im, $ibase.&parse-base($r).round(1e-10).narrow;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
use Base::Any;
|
||||
|
||||
# TESTING
|
||||
for 0, 2i, 1, 2i, 5, 2i, -13, 2i, 9i, 2i, -3i, 2i, 7.75-7.5i, 2i, .25, 2i, # base 2i tests
|
||||
5+5i, 2i, 5+5i, 3i, 5+5i, 4i, 5+5i, 5i, 5+5i, 6i, # same value, positive imaginary bases
|
||||
5+5i, -2i, 5+5i, -3i, 5+5i, -4i, 5+5i, -5i, 5+5i, -6i, # same value, negative imaginary bases
|
||||
227.65625+10.859375i, 4i, # larger test value
|
||||
31433.3487654321-2902.4480452675i, 6i, # heh
|
||||
-3544.29+26541.468i, -10i
|
||||
-> $v, $r {
|
||||
my $ibase = $v.&to-base($r, :precision(-6));
|
||||
printf "%33s.&to-base\(%3si\) = %-11s : %13s.&from-base\(%3si\) = %s\n",
|
||||
$v, $r.im, $ibase, "'$ibase'", $r.im, $ibase.&from-base($r).round(1e-10).narrow;
|
||||
}
|
||||
38
Task/Imaginary-base-numbers/Ruby/imaginary-base-numbers-1.rb
Normal file
38
Task/Imaginary-base-numbers/Ruby/imaginary-base-numbers-1.rb
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Convert a quarter-imaginary base value (as a string) into a base 10 Gaussian integer.
|
||||
|
||||
def base2i_decode(qi)
|
||||
return 0 if qi == '0'
|
||||
md = qi.match(/^(?<int>[0-3]+)(?:\.(?<frc>[0-3]+))?$/)
|
||||
raise 'ill-formed quarter-imaginary base value' if !md
|
||||
ls_pow = md[:frc] ? -(md[:frc].length) : 0
|
||||
value = 0
|
||||
(md[:int] + (md[:frc] ? md[:frc] : '')).reverse.each_char.with_index do |dig, inx|
|
||||
value += dig.to_i * (2i)**(inx + ls_pow)
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
# Convert a base 10 Gaussian integer into a quarter-imaginary base value (as a string).
|
||||
|
||||
def base2i_encode(gi)
|
||||
odd = gi.imag.to_i.odd?
|
||||
frac = (gi.imag.to_i != 0)
|
||||
real = gi.real.to_i
|
||||
imag = (gi.imag.to_i + 1) / 2
|
||||
value = ''
|
||||
phase_real = true
|
||||
while (real != 0) || (imag != 0)
|
||||
if phase_real
|
||||
real, rem = real.divmod(4)
|
||||
real = -real
|
||||
else
|
||||
imag, rem = imag.divmod(4)
|
||||
imag = -imag
|
||||
end
|
||||
value.prepend(rem.to_s)
|
||||
phase_real = !phase_real
|
||||
end
|
||||
value = '0' if value == ''
|
||||
value.concat(odd ? '.2' : '.0') if frac
|
||||
return value
|
||||
end
|
||||
46
Task/Imaginary-base-numbers/Ruby/imaginary-base-numbers-2.rb
Normal file
46
Task/Imaginary-base-numbers/Ruby/imaginary-base-numbers-2.rb
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# Extend class Integer with a string conveter.
|
||||
|
||||
class Integer
|
||||
def as_str()
|
||||
return to_s()
|
||||
end
|
||||
end
|
||||
|
||||
# Extend class Complex with a string conveter (works only with Gaussian integers).
|
||||
|
||||
class Complex
|
||||
def as_str()
|
||||
return '0' if self == 0
|
||||
return real.to_i.to_s if imag == 0
|
||||
return imag.to_i.to_s + 'i' if real == 0
|
||||
return real.to_i.to_s + '+' + imag.to_i.to_s + 'i' if imag >= 0
|
||||
return real.to_i.to_s + '-' + (-(imag.to_i)).to_s + 'i'
|
||||
end
|
||||
end
|
||||
|
||||
# Emit various tables of conversions.
|
||||
|
||||
1.step(16) do |gi|
|
||||
puts(" %4s -> %8s -> %4s %4s -> %8s -> %4s" %
|
||||
[gi.as_str, base2i_encode(gi), base2i_decode(base2i_encode(gi)).as_str,
|
||||
(-gi).as_str, base2i_encode(-gi), base2i_decode(base2i_encode(-gi)).as_str])
|
||||
end
|
||||
puts
|
||||
1.step(16) do |gi|
|
||||
gi *= 0+1i
|
||||
puts(" %4s -> %8s -> %4s %4s -> %8s -> %4s" %
|
||||
[gi.as_str, base2i_encode(gi), base2i_decode(base2i_encode(gi)).as_str,
|
||||
(-gi).as_str, base2i_encode(-gi), base2i_decode(base2i_encode(-gi)).as_str])
|
||||
end
|
||||
puts
|
||||
0.step(3) do |m|
|
||||
0.step(3) do |l|
|
||||
0.step(3) do |h|
|
||||
qi = (100 * h + 10 * m + l).to_s
|
||||
gi = base2i_decode(qi)
|
||||
md = base2i_encode(gi).match(/^(?<num>[0-3]+)(?:\.0)?$/)
|
||||
print(" %4s -> %6s -> %4s" % [qi, gi.as_str, md[:num]])
|
||||
end
|
||||
puts
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
func base (Number num, Number radix { _ ~~ (-36 .. -2) }, precision = -15) -> String {
|
||||
num || return '0'
|
||||
|
||||
var place = 0
|
||||
var result = ''
|
||||
var value = num
|
||||
var upper_bound = 1/(-radix + 1)
|
||||
var lower_bound = radix*upper_bound
|
||||
|
||||
while (!(lower_bound <= value) || !(value < upper_bound)) {
|
||||
value = num/(radix**++place)
|
||||
}
|
||||
|
||||
while ((value || (place > 0)) && (place > precision)) {
|
||||
var digit = (radix*value - lower_bound -> int)
|
||||
value = (radix*value - digit)
|
||||
result += '.' if (!place && !result.contains('.'))
|
||||
result += ((digit == -radix) ? (digit-1 -> base(-radix) + '0') : digit.base(-radix))
|
||||
place--
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func base (Number num, Number radix { .re == 0 }, precision = -8) -> String {
|
||||
|
||||
(radix.im.abs ~~ 2..6) || die "Base #{radix} out of range"
|
||||
|
||||
var (re, im) = (num.re, num.im)
|
||||
var (re_wh, re_fr='') = base(re, -radix.im**2, precision).split('.')...
|
||||
var (im_wh, im_fr='') = base(im/radix.im, -radix.im**2, precision).split('.')...
|
||||
|
||||
func zip (String a, String b) {
|
||||
var l = ('0' * abs(a.len - b.len))
|
||||
chars(a+l) ~Z chars(b+l) -> flat.join.sub(/0+\z/, '') || '0'
|
||||
}
|
||||
|
||||
var whole = zip(re_wh.flip, im_wh.flip).flip
|
||||
var fraction = zip(im_fr, re_fr)
|
||||
fraction == '0' ? whole : "#{whole}.#{fraction}"
|
||||
}
|
||||
|
||||
func parse_base (String str, Number radix { .re == 0 }) -> Number {
|
||||
|
||||
if (str.char(0) == '-') {
|
||||
return (-1 * parse_base(str.substr(1), radix))
|
||||
}
|
||||
|
||||
var (whole, frac='') = str.split('.')...
|
||||
|
||||
var fraction = frac.chars.map_kv {|k,v|
|
||||
Number(v, radix.im**2) * radix**-(k+1)
|
||||
}.sum
|
||||
|
||||
fraction += whole.flip.chars.map_kv {|k,v|
|
||||
Number(v, radix.im**2) * radix**k
|
||||
}.sum
|
||||
|
||||
return fraction
|
||||
}
|
||||
|
||||
var tests = [0, 2i, 1, 2i, 5, 2i, -13, 2i, 9i, 2i, -3i, 2i, 7.75-7.5i, 2i, .25, 2i, # base 2i tests
|
||||
5+5i, 2i, 5+5i, 3i, 5+5i, 4i, 5+5i, 5i, 5+5i, 6i, # same value, positive imaginary bases
|
||||
5+5i, -2i, 5+5i, -3i, 5+5i, -4i, 5+5i, -5i, 5+5i, -6i, # same value, negative imaginary bases
|
||||
227.65625+10.859375i, 4i] # larger test value
|
||||
|
||||
tests.each_slice(2, {|v,r|
|
||||
var ibase = base(v, r)
|
||||
printf("base(%20s, %2si) = %-10s : parse_base(%12s, %2si) = %s\n",
|
||||
v, r.im, ibase, "'#{ibase}'", r.im, parse_base(ibase, r).round(-8))
|
||||
})
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
Imports System.Text
|
||||
|
||||
Module Module1
|
||||
|
||||
Class Complex : Implements IFormattable
|
||||
Private ReadOnly real As Double
|
||||
Private ReadOnly imag As Double
|
||||
|
||||
Public Sub New(r As Double, i As Double)
|
||||
real = r
|
||||
imag = i
|
||||
End Sub
|
||||
|
||||
Public Sub New(r As Integer, i As Integer)
|
||||
real = r
|
||||
imag = i
|
||||
End Sub
|
||||
|
||||
Public Function Inv() As Complex
|
||||
Dim denom = real * real + imag * imag
|
||||
Return New Complex(real / denom, -imag / denom)
|
||||
End Function
|
||||
|
||||
Public Shared Operator -(self As Complex) As Complex
|
||||
Return New Complex(-self.real, -self.imag)
|
||||
End Operator
|
||||
|
||||
Public Shared Operator +(lhs As Complex, rhs As Complex) As Complex
|
||||
Return New Complex(lhs.real + rhs.real, lhs.imag + rhs.imag)
|
||||
End Operator
|
||||
|
||||
Public Shared Operator -(lhs As Complex, rhs As Complex) As Complex
|
||||
Return New Complex(lhs.real - rhs.real, lhs.imag - rhs.imag)
|
||||
End Operator
|
||||
|
||||
Public Shared Operator *(lhs As Complex, rhs As Complex) As Complex
|
||||
Return New Complex(lhs.real * rhs.real - lhs.imag * rhs.imag, lhs.real * rhs.imag + lhs.imag * rhs.real)
|
||||
End Operator
|
||||
|
||||
Public Shared Operator /(lhs As Complex, rhs As Complex) As Complex
|
||||
Return lhs * rhs.Inv
|
||||
End Operator
|
||||
|
||||
Public Shared Operator *(lhs As Complex, rhs As Double) As Complex
|
||||
Return New Complex(lhs.real * rhs, lhs.imag * rhs)
|
||||
End Operator
|
||||
|
||||
Public Function ToQuaterImaginary() As QuaterImaginary
|
||||
If real = 0.0 AndAlso imag = 0.0 Then
|
||||
Return New QuaterImaginary("0")
|
||||
End If
|
||||
Dim re = CType(real, Integer)
|
||||
Dim im = CType(imag, Integer)
|
||||
Dim fi = -1
|
||||
Dim sb As New StringBuilder
|
||||
While re <> 0
|
||||
Dim rm = re Mod -4
|
||||
re \= -4
|
||||
If rm < 0 Then
|
||||
rm += 4
|
||||
re += 1
|
||||
End If
|
||||
sb.Append(rm)
|
||||
sb.Append(0)
|
||||
End While
|
||||
If im <> 0 Then
|
||||
Dim f = (New Complex(0.0, imag) / New Complex(0.0, 2.0)).real
|
||||
im = Math.Ceiling(f)
|
||||
f = -4.0 * (f - im)
|
||||
Dim index = 1
|
||||
While im <> 0
|
||||
Dim rm = im Mod -4
|
||||
im \= -4
|
||||
If rm < 0 Then
|
||||
rm += 4
|
||||
im += 1
|
||||
End If
|
||||
If index < sb.Length Then
|
||||
sb(index) = Chr(rm + 48)
|
||||
Else
|
||||
sb.Append(0)
|
||||
sb.Append(rm)
|
||||
End If
|
||||
index += 2
|
||||
End While
|
||||
fi = f
|
||||
End If
|
||||
Dim reverse As New String(sb.ToString().Reverse().ToArray())
|
||||
sb.Length = 0
|
||||
sb.Append(reverse)
|
||||
If fi <> -1 Then
|
||||
sb.AppendFormat(".{0}", fi)
|
||||
End If
|
||||
Dim s = sb.ToString().TrimStart("0")
|
||||
If s(0) = "." Then
|
||||
s = "0" + s
|
||||
End If
|
||||
Return New QuaterImaginary(s)
|
||||
End Function
|
||||
|
||||
Public Overloads Function ToString() As String
|
||||
Dim r2 = If(real = -0.0, 0.0, real) 'get rid of negative zero
|
||||
Dim i2 = If(imag = -0.0, 0.0, imag) 'ditto
|
||||
If i2 = 0.0 Then
|
||||
Return String.Format("{0}", r2)
|
||||
End If
|
||||
If r2 = 0.0 Then
|
||||
Return String.Format("{0}i", i2)
|
||||
End If
|
||||
If i2 > 0.0 Then
|
||||
Return String.Format("{0} + {1}i", r2, i2)
|
||||
End If
|
||||
Return String.Format("{0} - {1}i", r2, -i2)
|
||||
End Function
|
||||
|
||||
Public Overloads Function ToString(format As String, formatProvider As IFormatProvider) As String Implements IFormattable.ToString
|
||||
Return ToString()
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Class QuaterImaginary
|
||||
Private Shared ReadOnly twoI = New Complex(0.0, 2.0)
|
||||
Private Shared ReadOnly invTwoI = twoI.Inv()
|
||||
|
||||
Private ReadOnly b2i As String
|
||||
|
||||
Public Sub New(b2i As String)
|
||||
If b2i = "" OrElse Not b2i.All(Function(c) "0123.".IndexOf(c) > -1) OrElse b2i.Count(Function(c) c = ".") > 1 Then
|
||||
Throw New Exception("Invalid Base 2i number")
|
||||
End If
|
||||
Me.b2i = b2i
|
||||
End Sub
|
||||
|
||||
Public Function ToComplex() As Complex
|
||||
Dim pointPos = b2i.IndexOf(".")
|
||||
Dim posLen = If(pointPos <> -1, pointPos, b2i.Length)
|
||||
Dim sum = New Complex(0.0, 0.0)
|
||||
Dim prod = New Complex(1.0, 0.0)
|
||||
For j = 0 To posLen - 1
|
||||
Dim k = Asc(b2i(posLen - 1 - j)) - Asc("0")
|
||||
If k > 0.0 Then
|
||||
sum += prod * k
|
||||
End If
|
||||
prod *= twoI
|
||||
Next
|
||||
If pointPos <> -1 Then
|
||||
prod = invTwoI
|
||||
For j = posLen + 1 To b2i.Length - 1
|
||||
Dim k = Asc(b2i(j)) - Asc("0")
|
||||
If k > 0.0 Then
|
||||
sum += prod * k
|
||||
End If
|
||||
prod *= invTwoI
|
||||
Next
|
||||
End If
|
||||
Return sum
|
||||
End Function
|
||||
|
||||
Public Overrides Function ToString() As String
|
||||
Return b2i
|
||||
End Function
|
||||
End Class
|
||||
|
||||
Sub Main()
|
||||
For i = 1 To 16
|
||||
Dim c1 As New Complex(i, 0)
|
||||
Dim qi = c1.ToQuaterImaginary()
|
||||
Dim c2 = qi.ToComplex()
|
||||
Console.Write("{0,4} -> {1,8} -> {2,4} ", c1, qi, c2)
|
||||
c1 = -c1
|
||||
qi = c1.ToQuaterImaginary()
|
||||
c2 = qi.ToComplex()
|
||||
Console.WriteLine("{0,4} -> {1,8} -> {2,4}", c1, qi, c2)
|
||||
Next
|
||||
Console.WriteLine()
|
||||
For i = 1 To 16
|
||||
Dim c1 As New Complex(0, i)
|
||||
Dim qi = c1.ToQuaterImaginary()
|
||||
Dim c2 = qi.ToComplex()
|
||||
Console.Write("{0,4} -> {1,8} -> {2,4} ", c1, qi, c2)
|
||||
c1 = -c1
|
||||
qi = c1.ToQuaterImaginary()
|
||||
c2 = qi.ToComplex()
|
||||
Console.WriteLine("{0,4} -> {1,8} -> {2,4}", c1, qi, c2)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
End Module
|
||||
112
Task/Imaginary-base-numbers/Wren/imaginary-base-numbers.wren
Normal file
112
Task/Imaginary-base-numbers/Wren/imaginary-base-numbers.wren
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
import "/complex" for Complex
|
||||
import "/fmt" for Fmt
|
||||
|
||||
class QuaterImaginary {
|
||||
construct new(b2i) {
|
||||
if (b2i.type != String || b2i == "" || !b2i.all { |d| "0123.".contains(d) } ||
|
||||
b2i.count { |d| d == "." } > 1) Fiber.abort("Invalid Base 2i number.")
|
||||
_b2i = b2i
|
||||
}
|
||||
|
||||
// only works properly if 'c.real' and 'c.imag' are both integral
|
||||
static fromComplex(c) {
|
||||
if (c.real == 0 && c.imag == 0) return QuaterImaginary.new("0")
|
||||
var re = c.real.truncate
|
||||
var im = c.imag.truncate
|
||||
var fi = -1
|
||||
var sb = ""
|
||||
while (re != 0) {
|
||||
var rem = re % (-4)
|
||||
re = (re/(-4)).truncate
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem
|
||||
re = re + 1
|
||||
}
|
||||
if (rem == -0) rem = 0 // get rid of minus zero
|
||||
sb = sb + rem.toString + "0"
|
||||
}
|
||||
if (im != 0) {
|
||||
var f = (Complex.new(0, c.imag) / Complex.imagTwo).real
|
||||
im = f.ceil
|
||||
f = -4 * (f - im)
|
||||
var index = 1
|
||||
while (im != 0) {
|
||||
var rem = im % (-4)
|
||||
im = (im/(-4)).truncate
|
||||
if (rem < 0) {
|
||||
rem = 4 + rem
|
||||
im = im + 1
|
||||
}
|
||||
if (index < sb.count) {
|
||||
var sbl = sb.toList
|
||||
sbl[index] = String.fromByte(rem + 48)
|
||||
sb = sbl.join()
|
||||
} else {
|
||||
if (rem == -0) rem = 0 // get rid of minus zero
|
||||
sb = sb + "0" + rem.toString
|
||||
}
|
||||
index = index + 2
|
||||
}
|
||||
fi = f.truncate
|
||||
}
|
||||
if (sb.count > 0) sb = sb[-1..0]
|
||||
if (fi != -1) {
|
||||
if (fi == -0) fi = 0 // get rid of minus zero
|
||||
sb = sb + ".%(fi)"
|
||||
}
|
||||
sb = sb.trimStart("0")
|
||||
if (sb.startsWith(".")) sb = "0" + sb
|
||||
return QuaterImaginary.new(sb)
|
||||
}
|
||||
|
||||
toComplex {
|
||||
var pointPos = _b2i.indexOf(".")
|
||||
var posLen = (pointPos != -1) ? pointPos : _b2i.count
|
||||
var sum = Complex.zero
|
||||
var prod = Complex.one
|
||||
for (j in 0...posLen) {
|
||||
var k = _b2i.bytes[posLen-1-j] - 48
|
||||
if (k > 0) sum = sum + prod * k
|
||||
prod = prod * Complex.imagTwo
|
||||
}
|
||||
if (pointPos != -1) {
|
||||
prod = Complex.imagTwo.inverse
|
||||
var j = posLen + 1
|
||||
while (j < _b2i.count) {
|
||||
var k = _b2i.bytes[j] - 48
|
||||
if (k > 0) sum = sum + prod * k
|
||||
prod = prod / Complex.imagTwo
|
||||
j = j + 1
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
toString { _b2i }
|
||||
}
|
||||
|
||||
var imagOnly = Fn.new { |c| c.imag.toString + "i" }
|
||||
|
||||
var fmt = "$4s -> $8s -> $4s"
|
||||
Complex.showAsReal = true
|
||||
for (i in 1..16) {
|
||||
var c1 = Complex.new(i, 0)
|
||||
var qi = QuaterImaginary.fromComplex(c1)
|
||||
var c2 = qi.toComplex
|
||||
Fmt.write("%(fmt) ", c1, qi, c2)
|
||||
c1 = -c1
|
||||
qi = QuaterImaginary.fromComplex(c1)
|
||||
c2 = qi.toComplex
|
||||
Fmt.print(fmt, c1, qi, c2)
|
||||
}
|
||||
System.print()
|
||||
for (i in 1..16) {
|
||||
var c1 = Complex.new(0, i)
|
||||
var qi = QuaterImaginary.fromComplex(c1)
|
||||
var c2 = qi.toComplex
|
||||
Fmt.write("%(fmt) ", imagOnly.call(c1), qi, imagOnly.call(c2))
|
||||
c1 = -c1
|
||||
qi = QuaterImaginary.fromComplex(c1)
|
||||
c2 = qi.toComplex
|
||||
Fmt.print(fmt, imagOnly.call(c1), qi, imagOnly.call(c2))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue