2014-12-18 10 views
6

Sto provando a scrivere una funzione di "fuzzy compare" in Rust.Quale tratto posso usare per un "confronto sfocato" di tipi numerici?

Ecco un esempio:

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

Ho un problema nel trasformare in una versione generica. Esiste un tratto che raggruppa numeri in virgola mobile e naturali, consentendo al tempo stesso di eseguire operazioni aritmetiche su di essi? Qualcosa di simile a questo:

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

Vorrei utilizzare questa funzione in casi come:

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

Ho già provato Ord tratto, ma non funziona:

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

Il tratto core::num::Num sembra essere deprecato, quindi non sto neanche provando a usarlo.

+3

Nota: questo sembra essere il tipico metodo "epsilon" per confrontare i numeri in virgola mobile, tuttavia occorre tenere presente che esiste un problema con questo metodo => variazioni di magnitudo. Un "epsilon" assoluto non funzionerà quando 'a' e' b' hanno una magnitudine significativamente più alta, perché allora 'b - epsilon == b' e' b + epsilon == b'. Non avrai il problema degli integrali, ovviamente. Per i punti mobili, quindi, potresti voler esaminare * epsilons relativi *; questo è 'abs (a - b)/max (abs (a), abs (b))

risposta

5

Non è necessario specificare che T dovrebbe essere un tipo di numero built-in, solo che deve supportare le addizione, sottrazione e confronto tratti richiesti dalla formula:

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

Ho appena trovato una soluzione simile. 'T: PartialOrd + Aggiungi + Sub + Copia'. – antonone

+0

Infatti, grazie per la correzione. Ho digitato troppo velocemente e non ho controllato l'intero caso d'uso dell'OP. Sopra post è stato modificato. – dummydev

Problemi correlati