{"id":1027,"date":"2013-06-20T21:15:41","date_gmt":"2013-06-20T19:15:41","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=1027"},"modified":"2013-06-23T13:53:13","modified_gmt":"2013-06-23T11:53:13","slug":"mathematik-ist-einfach-sie-auf-rechner-zu-bringen-nicht","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2013\/06\/20\/mathematik-ist-einfach-sie-auf-rechner-zu-bringen-nicht\/","title":{"rendered":"Mathematik ist einfach, sie auf Rechner zu bringen nicht&#8230;"},"content":{"rendered":"<p>Mathe ist ja eigentlich ganz einfach. Die nachfolgende Routine berechnet die k\u00fcrzeste Distanz zwischen zwei Punkten auf der Erde unter der Ber\u00fccksichtigung, dass die Erde eine perfekte Kugel ist.<br \/>\nBenutzt wird diese Routine um die Luftlinie zwischen zwei geokodierten Adressen zu ermitteln.<\/p>\n<pre lang=\"cpp\">double DistanceBetweenCoordinates(\r\n          double dLatitude1, double dLongitude1, \r\n          double dLatitude2, double dLongitude2)\r\n{\r\n  \/\/ Convert to radient\r\n  dLatitude1 *= M_PI \/ 180;\r\n  dLongitude1 *= M_PI \/ 180;\r\n  dLatitude2 *= M_PI \/ 180;\r\n  dLongitude2 *= M_PI \/ 180;\r\n\r\n  \/\/ Get distance\r\n  double dDistance;\r\n  dDistance = sin(dLatitude1) * sin(dLatitude2) + cos(dLatitude1) * \r\n        cos(dLatitude2) * cos(dLongitude2-dLongitude1);\r\n  \/\/ Ohne diese Zeile haben wir ein Problem... dDistance ist evtl. &gt;1\r\n  \/\/ dDistance = min(dDistance,1.0);\r\n  dDistance = acos(dDistance) * EARTH_RADIUS;\r\n  return dDistance;\r\n}<\/pre>\n<p>Eigentlich ganz einfach. Aber dieser Code hat ein massives Problem, denn <em>dDistance<\/em> kann vor dem <em>acos<\/em> durch Rundungsfehler\u00a0gr\u00f6\u00dfer\u00a0als 1 werden.<\/p>\n<p>F\u00fcr die folgenden Werte passiert etwas \u00dcbles:<\/p>\n<pre>dLatitude1 0.86208095750908087 \r\ndLongitude1 0.15333764167657613 \r\ndLatitude2 0.86208095750908087 \r\ndLongitude2 0.15333764167657613<\/pre>\n<p>Eigentlich m\u00fcsste glatt 1 herauskommen, denn die Koordinaten sind gleich, aber <span style=\"text-decoration: underline;\"><em>dDistance<\/em><\/span> wird bei diesen Werten <em>1.0000000000000002<\/em>. Der Sinus bzw. Cosinus ergibt eben doch leicht abweichende Werte. Der folgende <em>acos<\/em> scheitert dann aber und das Resultat wird <em>NaN<\/em> (Not a Number). Erlaubt sind nat\u00fcrlich nur Werte &lt;=1.0 und &gt;=-1.0. Die Folge ist, dass die Distanz nicht 0.0 ist.<\/p>\n<p>Also muss hier eine kleine Sicherung eingebaut werden, die Aufgrund der Rundungs-Genauigkeitsfehler, das \u00fcberschreiten von 1 verhindert.<br \/>\nEigentlich ist Mathe ganz einfach, aber auf einem Rechner ist das alles manchmal ganz anders.<\/p>\n<p>PS: Ich wei\u00df schon warum ich noch nie Flie\u00dfkommaarithmetik auf PCs mochte.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mathe ist ja eigentlich ganz einfach. Die nachfolgende Routine berechnet die k\u00fcrzeste Distanz zwischen zwei Punkten auf der Erde unter der Ber\u00fccksichtigung, dass die Erde eine perfekte Kugel ist. Benutzt wird diese Routine um die Luftlinie zwischen zwei geokodierten Adressen zu ermitteln. double DistanceBetweenCoordinates( double dLatitude1, double dLongitude1, double dLatitude2, double dLongitude2) { \/\/ Convert &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2013\/06\/20\/mathematik-ist-einfach-sie-auf-rechner-zu-bringen-nicht\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eMathematik ist einfach, sie auf Rechner zu bringen nicht&#8230;\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[30,19,3],"tags":[336,360],"class_list":["post-1027","post","type-post","status-publish","format-standard","hentry","category-c","category-crt","category-programmieren","tag-c-mathematik","tag-crt"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/1027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=1027"}],"version-history":[{"count":0,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/1027\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=1027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=1027"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=1027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}