Minkowski question-mark function: Difference between revisions

Content added Content deleted
(Added Perl)
(A Python implementation)
Line 493: Line 493:
-0.5657414540893351 -0.5657414540893352
-0.5657414540893351 -0.5657414540893352
0.7182818280000092 0.1213141516171819
0.7182818280000092 0.1213141516171819
</pre>

=={{header|Python}}==
{{trans|Go}}
<lang python>import math

MAXITER = 151


def minkowski(x):
if x > 1 or x < 0:
return math.floor(x) + minkowski(x - math.floor(x))

p = int(x)
q = 1
r = p + 1
s = 1
d = 1.0
y = float(p)

while True:
d /= 2
if y + d == y:
break

m = p + r
if m < 0 or p < 0:
break

n = q + s
if n < 0:
break

if x < m / n:
r = m
s = n
else:
y += d
p = m
q = n

return y + d


def minkowski_inv(x):
if x > 1 or x < 0:
return math.floor(x) + minkowski_inv(x - math.floor(x))

if x == 1 or x == 0:
return x

cont_frac = [0]
current = 0
count = 1
i = 0

while True:
x *= 2

if current == 0:
if x < 1:
count += 1
else:
cont_frac.append(0)
cont_frac[i] = count

i += 1
count = 1
current = 1
x -= 1
else:
if x > 1:
count += 1
x -= 1
else:
cont_frac.append(0)
cont_frac[i] = count

i += 1
count = 1
current = 0

if x == math.floor(x):
cont_frac[i] = count
break

if i == MAXITER:
break

ret = 1.0 / cont_frac[i]
for j in range(i - 1, -1, -1):
ret = cont_frac[j] + 1.0 / ret

return 1.0 / ret


if __name__ == "__main__":
print(
"{:19.16f} {:19.16f}".format(
minkowski(0.5 * (1 + math.sqrt(5))),
5.0 / 3.0,
)
)

print(
"{:19.16f} {:19.16f}".format(
minkowski_inv(-5.0 / 9.0),
(math.sqrt(13) - 7) / 6,
)
)

print(
"{:19.16f} {:19.16f}".format(
minkowski(minkowski_inv(0.718281828)),
minkowski_inv(minkowski(0.1213141516171819)),
)
)
</lang>

{{out}}
<pre>
1.6666666666696983 1.6666666666666667
-0.5657414540893351 -0.5657414540893352
0.7182818280000092 0.1213141516171819
</pre>
</pre>