Imaginary base numbers: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: Note support for minimum, extra kudos and stretch goals. Minor tidying.) |
(Added Go) |
||
Line 497: | Line 497: | ||
15 -> 102000.2 -> 16 -15 -> 2010.2 -> -14 |
15 -> 102000.2 -> 16 -15 -> 2010.2 -> -14 |
||
16 -> 102000.0 -> 16 -16 -> 2000.0 -> -16</pre> |
16 -> 102000.0 -> 16 -16 -> 2000.0 -> -16</pre> |
||
=={{header|Go}}== |
|||
{{trans|Kotlin}} |
|||
... though a bit shorter as Go has support for complex numbers built into the language. |
|||
<lang go>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)) |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
1 -> 1 -> 1 -1 -> 103 -> -1 |
|||
2 -> 2 -> 2 -2 -> 102 -> -2 |
|||
3 -> 3 -> 3 -3 -> 101 -> -3 |
|||
4 -> 10300 -> 4 -4 -> 100 -> -4 |
|||
5 -> 10301 -> 5 -5 -> 203 -> -5 |
|||
6 -> 10302 -> 6 -6 -> 202 -> -6 |
|||
7 -> 10303 -> 7 -7 -> 201 -> -7 |
|||
8 -> 10200 -> 8 -8 -> 200 -> -8 |
|||
9 -> 10201 -> 9 -9 -> 303 -> -9 |
|||
10 -> 10202 -> 10 -10 -> 302 -> -10 |
|||
11 -> 10203 -> 11 -11 -> 301 -> -11 |
|||
12 -> 10100 -> 12 -12 -> 300 -> -12 |
|||
13 -> 10101 -> 13 -13 -> 1030003 -> -13 |
|||
14 -> 10102 -> 14 -14 -> 1030002 -> -14 |
|||
15 -> 10103 -> 15 -15 -> 1030001 -> -15 |
|||
16 -> 10000 -> 16 -16 -> 1030000 -> -16 |
|||
1i -> 10.2 -> 1i -1i -> 0.2 -> -1i |
|||
2i -> 10.0 -> 2i -2i -> 1030.0 -> -2i |
|||
3i -> 20.2 -> 3i -3i -> 1030.2 -> -3i |
|||
4i -> 20.0 -> 4i -4i -> 1020.0 -> -4i |
|||
5i -> 30.2 -> 5i -5i -> 1020.2 -> -5i |
|||
6i -> 30.0 -> 6i -6i -> 1010.0 -> -6i |
|||
7i -> 103000.2 -> 7i -7i -> 1010.2 -> -7i |
|||
8i -> 103000.0 -> 8i -8i -> 1000.0 -> -8i |
|||
9i -> 103010.2 -> 9i -9i -> 1000.2 -> -9i |
|||
10i -> 103010.0 -> 10i -10i -> 2030.0 -> -10i |
|||
11i -> 103020.2 -> 11i -11i -> 2030.2 -> -11i |
|||
12i -> 103020.0 -> 12i -12i -> 2020.0 -> -12i |
|||
13i -> 103030.2 -> 13i -13i -> 2020.2 -> -13i |
|||
14i -> 103030.0 -> 14i -14i -> 2010.0 -> -14i |
|||
15i -> 102000.2 -> 15i -15i -> 2010.2 -> -15i |
|||
16i -> 102000.0 -> 16i -16i -> 2000.0 -> -16i |
|||
</pre> |
|||
=={{header|Java}}== |
=={{header|Java}}== |