Zaimplementowałem algorytm dla ułamka dziesiętnego zmiennoprzecinkowego do racjonalnego przybliżenia ułamka (przykład: 0.333 -> 1/3) i teraz zastanawiam się, czy istnieje sposób na znalezienie liczby irracjonalnej, która spełnia warunek. Na przykład, biorąc pod uwagę dane wejściowe 0.282842712474, chcę, aby wynik był równy sqrt (2)/5, a nie 431827/1526739, który generuje mój algorytm. Jedynym warunkiem jest to, że pierwsze cyfry wyniku (przekształcone z powrotem na zmiennoprzecinkowe) powinny być cyframi danych wejściowych, reszta nie ma znaczenia. Z góry dziękuję!Aproksymacja od dziesiętnej do irracjonalnej
6
A
Odpowiedz
2
Wpadłem na rozwiązanie, które z danego zestawu możliwych mianowników i nominatorów znajduje najlepsze przybliżenie podanej liczby.
Przykładowo ten zestaw może zawierać wszystkie numery, które mogą być utworzone przez:
= radicand < = 100000
= root_index < = 20
Jeśli zestaw zawiera N elementów, niż ten roztwór znajdzie najlepsze przybliżenie w O (N log N).
W tym rozwiązaniu X oznacza mianownik i nominator Y.
- sortować numery z zestawu
- dla każdej liczby X z zestawu:
wykorzystujące binarny znaleźć najmniejszy Y takie, że Y/X> = input_number
porównać Y/X z aktualnie najlepszą zbliżenia input_number
nie mogłem się oprzeć i wdrożone go:
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
struct Number {
// number value
double value;
// number representation
int root_index;
int radicand;
Number(){}
Number(double value, int root_index, int radicand)
: value(value), root_index(root_index), radicand(radicand) {}
bool operator < (const Number& rhs) const {
// in case of equal numbers, i want smaller radicand first
if (fabs(value - rhs.value) < 1e-12) return radicand < rhs.radicand;
return value < rhs.value;
}
void print() const {
if (value - (int)value < 1e-12) printf("%.0f", value);
else printf("sqrt_%d(%d)",root_index, radicand);
}
};
std::vector<Number> numbers;
double best_result = 1e100;
Number best_numerator;
Number best_denominator;
double input;
void compare_approximpation(const Number& numerator, const Number& denominator) {
double value = numerator.value/denominator.value;
if (fabs(value - input) < fabs(best_result - input)) {
best_result = value;
best_numerator = numerator;
best_denominator = denominator;
}
}
int main() {
const int NUMBER_LIMIT = 100000;
const int ROOT_LIMIT = 20;
// only numbers created by this loops will be used
// as numerator and denominator
for(int i=1; i<=ROOT_LIMIT; i++) {
for(int j=1; j<=NUMBER_LIMIT; j++) {
double value = pow(j, 1.0 /i);
numbers.push_back(Number(value, i, j));
}
}
sort(numbers.begin(), numbers.end());
scanf("%lf",&input);
int numerator_index = 0;
for(int denominator_index=0; denominator_index<numbers.size(); denominator_index++) {
// you were interested only in integral denominators
if (numbers[denominator_index].root_index == 1) {
// i use simple sweeping technique instead of binary search (its faster)
while(numerator_index < numbers.size() && numbers[numerator_index].root_index &&
numbers[numerator_index].value/numbers[denominator_index].value <= input) {
numerator_index++;
}
// comparing approximations
compare_approximpation(numbers[numerator_index], numbers[denominator_index]);
if (numerator_index > 0) {
compare_approximpation(numbers[numerator_index - 1], numbers[denominator_index]);
}
}
}
printf("Best approximation %.12lf = ", best_numerator.value/best_denominator.value);
best_numerator.print();
printf("/");
best_denominator.print();
printf("\n");
}
Powiązane problemy
- 1. Jak zatrzymać parseFloat() od zerowania zera do prawej części dziesiętnej
- 2. Przesyłaj obiekt do postaci dziesiętnej? (Pustych dziesiętny)
- 3. Wywoływanie klasy dziesiętnej
- 4. Przypisanie zmiennej dziesiętnej SQL Server?
- 5. Obliczanie wartości dziesiętnej na Pythonie
- 6. Jak działa ta aproksymacja podziału za pomocą operacji zmiany bitowej?
- 7. Problem z analizą liczby dziesiętnej
- 8. pobranie części ułamkowej liczby dziesiętnej
- 9. Lepsza implementacja Ruby rundy dziesiętnej do najbliższej 0.5
- 10. Stosując krycie do formularza, należy użyć wartości dziesiętnej lub podwójnej?
- 11. Korekcja błędów na krótkiej liczbie dziesiętnej
- 12. WebAPI, JSON.Net i utrata dokładności dziesiętnej
- 13. Określanie skali dziesiętnej MAX używanej na kolumnie
- 14. jQuery animacja przyrost liczby dziesiętnej/dekrementacja
- 15. C++ setprecision (2) drukowanie jednej wartości dziesiętnej?
- 16. Jak zrobić Integer.parseInt() dla liczby dziesiętnej?
- 17. Parsowanie wartości dziesiętnej z ciągu w Ruby
- 18. Decimal.TryParse nie analizuje mojej wartości dziesiętnej
- 19. Konwersja liczby dziesiętnej na liczbę mieszaną (podstawową)
- 20. Jak przycinać zera po kropce dziesiętnej
- 21. Wspólna podpowiedź Highcharts wymaga innej wartości i różnej liczby dziesiętnej.
- 22. Dlaczego nie mogę rozpakować int jako kropki dziesiętnej?
- 23. Zdobądź ostatnie (tzn. Endswith) 3 cyfry dziesiętnej (.NET)
- 24. od byteArray do bigInteger
- 25. Od PDF do String
- 26. Od Arraylist do Array
- 27. Od barycentrycznego do kartezjańskiego
- 28. Od IPLImage do Mat
- 29. Od datatable do Entity
- 30. Od MVC do MVVM
można by przynajmniej należy umieścić trochę c ograniczenia dotyczące możliwych wyników. Czy interesują Cię tylko liczby całkowite z liczb całkowitych? –
"Jedyny warunek" nie wydaje się być zgodny z wymaganiem "sqrt (2)/5": Twój racjonalny R + sqrt (2)/10^k dla niektórych dużych k może działać inaczej. – DSM
Jeśli są tylko pierwiastki kwadratowe w liczniku i/lub mianowniku, które Cię interesują, dlaczego, możesz wyrównać dane wejściowe przed podaniem ich do swojego algorytmu. Ale, oczywiście, jest to pokonane przez liczby tak proste, jak sinus 15 stopni, który jest (sqrt (3,0) -1,0)/(2,0 * sqrt (2,0)). – thb