Następujący kod w języku C# nie działa:Jaki jest najlepszy sposób porównania Double i Int?
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
Więc pytanie: jaki jest najlepszy sposób, aby porównać podwójne i Int?
Następujący kod w języku C# nie działa:Jaki jest najlepszy sposób porównania Double i Int?
int iValue = 0;
double dValue = 0.0;
bool isEqual = iValue.Equals(dValue);
Więc pytanie: jaki jest najlepszy sposób, aby porównać podwójne i Int?
Naprawdę nie można porównać wartości zmiennoprzecinkowych i całkowych w sposób naiwny; w szczególności, ponieważ jest klasyczny: floating pointrepresentation challenges. Co ty może zrobić to odjąć od siebie i sprawdzić, czy różnica między nimi jest mniejsza niż pewna precyzja Ci zależy, tak jak poniżej:
int iValue = 0;
double dValue = 0.0;
var diff = Math.Abs(dvalue - iValue);
if(diff < 0.0000001) // need some min threshold to compare floating points
return true; // items equal
naprawdę trzeba określić dla siebie, co equality
oznacza dla Ciebie . Na przykład, możesz chcieć, aby wartość zmiennoprzecinkowa zaokrąglała w kierunku najbliższej liczby całkowitej, tak aby 3.999999981 była "równa" do 4. Możesz też skrócić wartość, aby była efektywna 3. Wszystko zależy od tego, co Ty próbuję to osiągnąć.
EDIT: Uwaga że wybrałem 0,0000001 jako wartość progową przykład ... musisz sam zdecydować, co jest wystarczające dla precyzyjnego porównania. Po prostu zdaj sobie sprawę, że musisz znajdować się w normalnych granicach reprezentacyjnych double
, które według mnie są zdefiniowane jako Double.Espilon
.
To jest dobre rozwiązanie problemu, o którym wspomniałem. Dla większej dokładności (tylko gdy jest to konieczne), używaj tylko liczb całkowitych, jak zasugerowałem w mojej odpowiedzi. –
Czy lepiej porównać ze stałą systemową epsilon zdefiniowaną przez system (zobacz tutaj http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx) zamiast wartości zakodowanej na stałe, np. 0.0000001? NB Nigdy nie kodowałem C# (tylko C++), ale zakładam, że ta sama zasada obowiązuje – pxb
Wspominam o tym w edytorze mojej odpowiedzi. Epsilon może, ale nie musi być dobrym wyborem, w zależności od tego, jaką precyzję OP obchodzi w swoim kodzie. – LBushkin
To naprawdę zależy od tego, co uważasz za "równe". Jeśli chcesz, aby Twoje porównanie wrócić prawdziwe wtedy i tylko wtedy, gdy dwukrotnie dokładnie pasuje do wartości całkowitej (czyli nie ma składnik ułamkowej), należy oddać int do podwójnego zrobić porównania:
bool isEqual = (double)iValue == dValue;
jeśli coś 1.1 byłby uważany za równy 1, możesz rzucić podwójny do int (jeśli chcesz całkowicie zignorować element ułamkowy) lub zaokrąglić podwójny, jeśli chcesz powiedzieć 1,9 na równe 2.
To niezmiernie zły pomysł porównać liczby całkowite i liczby zmiennoprzecinkowe dla równości w dowolnym języku. Działa to w bardzo prostych przypadkach, ale po wykonaniu jakiejkolwiek matematyki prawdopodobieństwo, że program robi to, co chcesz, dramatycznie się zmniejsza.
Ma to związek ze sposobem, w jaki liczby zmiennoprzecinkowe są przechowywane w cyfrowym systemie binarnym.
Jeśli jesteś bardzo pewny, że chcesz tego użyć, utwórz klasę, aby utworzyć własny numer z ułamkami. używaj jednej int do zachowania liczby całkowitej, a innej int do utrzymania frakcji.
Obecnie tylko o tylko raz jeden powinno być porównanie wartości typów double
i albo integer
lub long
ścisłej równości jest, gdy z jakiegoś powodu jeden jest zablokowany przechowywania lub przechodząc integralne ilości jako wartości zmiennoprzecinkowych i późniejszych potrzeb aby je przekonwertować. Taka konwersja może w większości przypadków być najłatwiejsza poprzez odlanie typu całkowego na double
, a następnie porównanie wyniku tego rzutu. Zauważ, że konwersja z long
na double
może być niedokładna, jeśli liczba jest poza zakresem ± 2 . Niemniej jednak, w czasach przed udostępnieniem 64-bitowego long
, double
był podręcznym typem pamięci dla liczb całkowitych, które były zbyt duże dla 32-bitowego int
, ale wystarczająco małe, aby obsłużyć je double
.
Zauważ, że konwertowania long
do double
a następnie robi porównanie przyniesie to rezultat „równe”, jeżeli wartość nominalna double
nie dokładnie dopasować wartość long
, ale reprezentuje najbliższy możliwy double
do tej wartości. Takie zachowanie ma sens, jeśli rozpoznaje się, że zmiennoprzecinkowe typy w rzeczywistości nie reprezentują pojedynczej dokładnej wartości, a raczej zakres wartości.
double val1 = 0;
double val2 = 0.0;
if((val1 - Double.Epsilon) < 0)
{
// Put your code here
}
OR
if((val2 - Double.Epsilon) < 0)
{
// Put your code here
}
gdzie Double.Epsilon jest najniższą możliwą wartością dla Double.
Zobacz to powiązane pytanie: –
Konamiman
[Jaki jest najbardziej skuteczny sposób na unoszenie się i podwójne porównywanie?] (Http: // stackoverflow.com/q/17333/995714) –