1 | // Copyright (C) 2016 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qmultimediautils_p.h" |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | Fraction qRealToFraction(qreal value) |
9 | { |
10 | int integral = int(floor(x: value)); |
11 | value -= qreal(integral); |
12 | if (value == 0.) |
13 | return {.numerator: integral, .denominator: 1}; |
14 | |
15 | const int dMax = 1000; |
16 | int n1 = 0, d1 = 1, n2 = 1, d2 = 1; |
17 | qreal mid = 0.; |
18 | while (d1 <= dMax && d2 <= dMax) { |
19 | mid = qreal(n1 + n2) / (d1 + d2); |
20 | |
21 | if (qAbs(t: value - mid) < 0.000001) { |
22 | break; |
23 | } else if (value > mid) { |
24 | n1 = n1 + n2; |
25 | d1 = d1 + d2; |
26 | } else { |
27 | n2 = n1 + n2; |
28 | d2 = d1 + d2; |
29 | } |
30 | } |
31 | |
32 | if (d1 + d2 <= dMax) |
33 | return {.numerator: n1 + n2 + integral * (d1 + d2), .denominator: d1 + d2}; |
34 | else if (d2 < d1) |
35 | return { .numerator: n2 + integral * d2, .denominator: d2 }; |
36 | else |
37 | return { .numerator: n1 + integral * d1, .denominator: d1 }; |
38 | } |
39 | |
40 | QT_END_NAMESPACE |
41 |