Convert decimal number to rational: Difference between revisions

Line 2,620:
dbl2frac 0.518518 -> 14 27, expected 42 81
~ $
 
=={{header|Vala}}==
{{trans|C}}
<lang vala>struct Fraction {
public long d;
public long n;
}
 
Fraction rat_approx(double f, long md) {
long a;
long[] h = {0, 1, 0};
long[] k = {1, 0, 0};
long x, d, n = 1;
bool neg = false;
if (md <= 1) return {1, (long)f};
if (f < 0) {
neg = true;
f = -f;
}
while (f != Math.floor(f)) {
n <<= 1;
f *= 2;
}
d = (long)f;
for (int i = 0; i < 64; i++) {
a = (n != 0) ? d / n : 0;
if (i != 0 && a == 0) break;
x = d; d = n; n = x %n;
x = a;
if (k[1] * a + k[0] >= md) {
x = (md - k[0]) / k[1];
if (x * 2 >= a || k[1] >= md)
i = 65;
else
break;
}
h[2] = x * h[1] + h[0]; h[0] = h[1]; h[1] = h[2];
k[2] = x * k[1] + k[0]; k[0] = k[1]; k[1] = k[2];
}
return {k[1], neg ? -h[1] : h[1]};
}
 
void main() {
double f;
 
stdout.printf("f = %16.14f\n", f = 1.0/7);
for (int i = 1; i < 20000000; i *= 16) {
stdout.printf("denom <= %11d: ", i);
var r = rat_approx(f, i);
stdout.printf("%11ld/%11ld\n", r.n, r.d);
}
 
stdout.printf("f = %16.14f\n", f = Math.atan2(1,1) * 4);
for (int i = 1; i < 20000000; i *= 16) {
stdout.printf("denom <= %11d: ", i);
var r = rat_approx(f, i);
stdout.printf("%11ld/%11ld\n", r.n, r.d);
}
}</lang>
 
{{out}}
<pre>
f = 0.14285714285714
denom <= 1: 0/ 1
denom <= 16: 1/ 7
denom <= 256: 1/ 7
denom <= 4096: 1/ 7
denom <= 65536: 1/ 7
denom <= 1048576: 1/ 7
denom <= 16777216: 1/ 7
f = 3.14159265358979
denom <= 1: 3/ 1
denom <= 16: 22/ 7
denom <= 256: 355/ 113
denom <= 4096: 355/ 113
denom <= 65536: 104348/ 33215
denom <= 1048576: 3126535/ 995207
denom <= 16777216: 47627751/ 15160384
</pre>
 
=={{header|zkl}}==
Anonymous user