| Bytes | Lang | Time | Link |
|---|---|---|---|
| 058 | Python 3 | 250513T233157Z | Lucenapo |
| 076 | Maple | 250513T161558Z | dharr |
| 069 | Charcoal | 250512T223646Z | Neil |
| 070 | JavaScript Node.js | 250513T095150Z | l4m2 |
| 024 | Uiua 0.16.0dev.2 | 250512T192131Z | Tbw |
Python 3, 61 58 bytes
f=lambda x:0<x<=.5and f(x/(1-x))/2or x and-f(0-x%-1)-x//-1
This answer gives a recurrence relation for the Minkowski question-mark function, so I just used the recurrence.
The input must be a fractions.Fraction object (which I believe is allowed as it is a native rational type).
Maple, 83 76 bytes
s->(a:=convert(s,confrac))[1]+2*add((-1)^m/2^add(a[j],j=2..m),m=2..nops(a));
Input and output are rationals. Calculates Minkowski's question mark function.
Charcoal, 69 bytes
NθNη‹θ⁰≦↔θ⍘÷θη²≧﹪ηθ.≔E²ιζF²⊞υ¹W⁻×θ§υ⁰×η§ζ⁰«≔‹×θΣυ×ηΣζεI¬ε§≔ζεΣζ§≔υεΣυ
Try it online! Link is to verbose version of code. Takes input as the numerator and denominator of a fraction (this does not need to be fully reduced) and outputs in binary. Explanation:
NθNη
Input the fraction.
‹θ⁰≦↔θ
If it is negative then print a - and remove the sign.
⍘÷θη²≧﹪ηθ.
Output the integer part of the fraction in binary, leaving the fractional part.
≔E²ιζF²⊞υ¹
Start a traversal of the Stern-Brocot tree with 0/1 as the lower bound and 1/1 as the upper bound.
W⁻×θ§υ⁰×η§ζ⁰«
Repeat until the input is found.
≔‹×θΣυ×ηΣζε
Calculate whether the input is below the next fraction.
I¬ε
Output 0 if it is and 1 if it is not.
§≔ζεΣζ§≔υεΣυ
Update the relevant bound.
Previous 60-byte attempt only mapped ℚ into ℤ[1/2] ∩ (1, 1):
NθNη‹θ⁰≦↔θ0.F²⊞υι≔⮌υζW⁻×θ§ζ⁰×η§υ⁰«≔‹×θΣζ×ηΣυεI¬ε§≔υεΣυ§≔ζεΣζ
Try it online! Link is to verbose version of code. Takes input as the numerator and denominator of a fraction (this does not need to be fully reduced) and outputs a the binary representation of a fraction. Explanation:
NθNη
Input the fraction.
‹θ⁰≦↔θ
If it is negative then print a - and remove the sign.
0.
Output the leading 0. of the binary fraction. (The output is always in the open range (-1, 1).)
F²⊞υι≔⮌υζ
Start a traversal of the Stern-Brocot tree with 0/1 as the lower bound and 1/0 as the upper bound.
W⁻×θ§ζ⁰×η§υ⁰«
Repeat until the input is found.
≔‹×θΣζ×ηΣυε
Calculate whether the input is below the next fraction.
I¬ε
Output 0 if it is and 1 if it is not.
§≔υεΣυ§≔ζεΣζ
Update the relevant bound.
JavaScript (Node.js), 75 70 bytes
f=(x,y)=>x<0?f(x+y,y)-1:x&&(x/y|0)+((x%=y)<(y-=x)?f(x,y):f(x+x-y,x))/2
Uiua 0.16.0-dev.2, 36 24 bytes SBCS
+/-⇌ⁿ⊙1/2-1\+:°⊂⌊⍢˜⟜⊃◿÷±
Takes p q on stack and outputs as a float. Both solutions compute Minkowski's \$?(p/q)\$, but in very different ways.
Explanation
⌊⍢˜⟜⊃◿÷± # continued fraction expansion
:°⊂ # take off a_0 and save it for later
-1\+ # running sum starting at -1
ⁿ⊙1/2 # 1/2^n
/-⇌ # alternating sum
+ # add a_0 back
Old solution
+÷-1⊃⧻˜⊗⍥(⊏⍏≡/÷.⊂⟜⧈+):⊞≤.⇡2⊙⊓⊂⌊⟜⊃⟜◿÷
Takes b a on stack for rational \$\frac{a}{b}\$ and outputs a float.
Explanation
⊙⊓⊂⌊⟜⊃⟜◿÷ # stack afterwards: b | [b, a mod b] | floor(a/b)
⍥(⊏⍏≡/÷.⊂⟜⧈+):⊞≤.⇡2 # compute successive mediants, i.e. the Farey sequence of order b
˜⊗ # at what index is a/b?
÷-1⊃⧻ # divide by length of sequence minus 1
+ # add back the integer part