Überschneiden sich die beiden Linien in einer kartesischen Ebene

7

Ich habe dieses Problem aus dem Buch "Crack the Coding Interview".

  

Bestimmen Sie bei zwei Linien in einer kartesischen Ebene, ob sich die beiden Linien schneiden würden.

Hier ist die Lösung:

%Vor%

Warum hat es nicht die einfache Lösung, dass, wenn die Steigungen nicht gleich sind, sie sich schneiden. Warum das Epsilon und das Y abfangen.

In den Vorschlägen heißt es, dass

  

Gehen Sie nicht davon aus, dass die Steigung und der y-Schnittpunkt ganze Zahlen sind. Verstehen Sie die Einschränkungen von Gleitkommadarstellungen. Niemals mit == auf Gleichheit prüfen.

    
Kraken 05.11.2012, 13:52
quelle

4 Antworten

9

Die "Lösung" ist falsch.

Implizit in dieser "Lösung" ist eine Vorstellung, dass die übergebenen Argumente ungenau sind, dass, bevor intersect aufgerufen wird, die Werte Berechnungen unterzogen wurden, die Ergebnisse mit Rundungsfehlern erzeugen können. Da es in den Werten Fehler gibt, sind Zahlen, die bei genauem Berechnen gleich wären, ungleich. Um diese als gleich zu erkennen, akzeptiert diese "Lösung" einige tatsächlich ungleiche Werte als gleich.

Ein Fehler in dieser Argumentation besteht darin, dass die Routine intersect keine Kenntnis davon hat, wie groß die Fehler sein können, und daher keine Grundlage hat, zu wissen, welchen Wert von epsilon sie verwenden soll. Der ideale Wert könnte Null sein, oder es könnte eine Million sein. Der Wert, der verwendet wird, 1e-5, basiert aufgrund der bereitgestellten Informationen nicht auf einem technischen Prinzip. Mehr als das gibt es keine Grundlage für die Verwendung eines absoluten Fehlers, wie dieser Code tut. Abhängig von den Umständen kann die richtige Toleranz für die Verwendung ein relativer Fehler sein, ein Fehler, der in ULPs oder einer anderen Technik angegeben wird. Es gibt einfach keinen Grund zu der Annahme, dass dieser Code true zurückgibt, wenn Argumente übergeben werden, die idealerweise sich schneidende Linien darstellen, aber auf eine unbekannte Weise berechnet wurden.

Ein weiterer Fehler ist, dass die Routine fälschlicherweise als gleiche Werte akzeptiert, die nicht gleich sind. Die Routine meldet, dass sich nicht viele Linien überschneiden, die sich schneiden. Dieser Code hat das Problem der Routine, die die falsche Antwort zurückgibt, nicht gelöst; es hat nur die Fälle geändert, für die falsche Antworten zurückgegeben werden, und es hat möglicherweise die Anzahl der falschen Antworten stark erhöht.

    
Eric Postpischil 05.11.2012, 15:00
quelle
5

Erstens, weil die einfache Lösung, wenn die Steigungen nicht die gleichen sind, die sie schneiden, nicht vollständig ist. Sie könnten dieselbe Steigung und denselben Schnittpunkt haben und wären daher identisch.

Das Epsilon, wie der Vorschlag sagt, ist, weil die Zahlendarstellung in Computern nicht genau ist. Laut dem IEEE-Standard hat ein Double etwa 15 präzise berechnete Stellen, daher können Steigung und Schnittpunkt einen Rundungsfehler haben zu vorherigen Berechnungen und daher könnte eine einfache Überprüfung mit == ergeben, dass sie nicht identisch sind, während sie sich nur durch einen Rundungsfehler unterscheiden.

    
Trudbert 05.11.2012 14:05
quelle
4
  

Warum hat es nicht die einfache Lösung, wenn die Steigungen nicht sind   gleich, dann werden sie sich schneiden. Warum das Epsilon und das Y abfangen.

Die Lösung berücksichtigt die Näherungsfehler aufgrund von Fließkomma Arithmetik. Da Fließkommazahlen nicht alle möglichen reellen Zahlen repräsentieren, sondern eine relativ kleine Teilmenge (dichter in [-1, + 1] Intervallen), ist es üblich, wenn Sie mit Gleitkommaarithmetik umgehen müssen, einen Schwellenwert zur Durchführung der Gleichheit zu verwenden überprüft.

Das epsilon valure repräsentiert einen Schwellenwert, unter dem 2 verschiedene Fließkommawerte als gleich betrachtet werden.

    
Heisenbug 05.11.2012 14:02
quelle
1

Darunter werden alle Zahlen bei der Verarbeitung in Binärwerte umgewandelt. Es ist nicht möglich, die meisten Fließkommazahlen als exakte Binärzahl darzustellen (weil sie eine unendliche Folge von 1en und 0en wären), und so werden Annäherungen gemacht, indem die binäre Sequenz abgeschnitten wird. Zum Beispiel ist die Gleitkommazahl 0,1 (dh ein Zehntel) nicht als exakte Binärzahl darstellbar, sondern wird durch eine Näherung dargestellt, die wie 0,000110011 aussieht ... Das Abschneiden dieser Binärzahl verursacht potentielle Rundungsfehler und so die exakte Gleichheit "==" könnte eine falsche Antwort verursachen, wenn es tatsächlich dieser Rundungsfehler ist, der das falsche Negativ gibt. Die Einführung eines Epsilons versucht, diese Fehler zu vermeiden, indem es sagt "alles, was unter dieser Zahl liegt, die wir für null halten". Weitere Informationen finden Sie im Abschnitt "Bruchteile im Binärformat" von wikipedia .

    
GarethL 05.11.2012 14:12
quelle

Tags und Links