2014-12-18 10 views
6

Próbuję napisać funkcję "fuzzy compare" w Rust.Jaką cechę mogę użyć do "porównania rozmytego" typów liczbowych?

Oto przykład:

fn fuzzy_cmp(a: f64, b: f64, tolerance: f64) -> bool { 
    a >= b - tolerance && a <= b + tolerance 
} 

Mam problem w przekształcając go w wersji generycznej. Czy istnieje cecha, która grupuje liczby naturalne i zmiennoprzecinkowe, pozwalając jednocześnie na wykonywanie operacji arytmetycznych? Coś takiego:

fn fuzzy_cmp<T: Numbers>(a: T, b: T, tolerance: T) -> bool { 
    a >= b - tolerance && a <= b + tolerance 
} 

Chciałbym skorzystać z tej funkcji w przypadkach takich jak:

fuzzy_cmp(x, 20u64, 5u64) 
fuzzy_cmp(y, 20f64, 5f64) 
// ... etc 

Ja już próbowałem Ord cechę, ale to nie działa:

28:23 error: binary operation `-` cannot be applied to type `T` 
a >= b - tolerance && a <= b + tolerance 
    ^~~~~~~~~~~~~ 

Cecha core::num::Num wydaje się być przestarzała, więc nawet nie próbuję jej użyć.

+3

Uwaga: To wydaje się być typowa metoda "epsilon" do porównywania liczb zmiennoprzecinkowych, ale należy pamiętać, że istnieje problem z tą metodą => zmiany wielkości. Absolutny "epsilon" nie zadziała, gdy "a" i "b" mają znacznie większą wartość, ponieważ wtedy "b - epsilon == b" i "b + epsilon == b". Oczywiście nie będziesz mieć problemu z całkami. W przypadku punktów zmiennoprzecinkowych możesz chcieć zbadać * względne * epsilony; to jest 'abs (a - b)/max (abs (a), abs (b))

Odpowiedz

5

Nie trzeba określić, że T powinien być wbudowany typ numeru, tylko że musi wspierać dodawanie, odejmowanie i porównania cech wymaganych przez wzoru:

fn fuzzy_cmp<T: Add<T, T> + Sub<T, T> + PartialOrd>(a: T, b: T, tolerance: T) -> bool { 
    a >= b - tolerance && a <= b + tolerance 
} 
+0

Właśnie wymyśliłem podobne rozwiązanie. 'T: PartialOrd + Dodaj + Sub + Copy'. – antonone

+0

Rzeczywiście, dzięki za poprawkę. Pisałem zbyt szybko i nie sprawdzałem całej sytuacji użycia OP. Powyższy post został zmodyfikowany. – dummydev

Powiązane problemy