Brauche Hilfe beim Programmieren: bei Geschwindigkeit den Ausgabewert begrenzen.

  • Antworten:12
  • Bentwortet
Sam Browder
  • Forum-Beiträge: 236

01.12.2012, 22:06:16 via Website

Hallo!
Ich habe folgendes Problem. Wenn ich eine Geschwindigkeitsberechnung anstelle in z. B. m/s
1double speed = location.getSpeed();
und dann das Ergebnis in einer TextView anzeigen lasse
1txt_ms_show.setText(speed+" m/s");
bekomme ich eine riesige Zahl mit zicht Stellen nach dem Komma.
Meine Frage ist, ob man die Zahl bis auf 3 Stellen hinter dem Komma begrenzen kann, und zwar mit mathematischer Aufrundung.
Danke im Voraus.

— geändert am 01.12.2012, 22:07:26

Antworten
San Blarnoi
  • Forum-Beiträge: 2.545

02.12.2012, 00:03:47 via Website

format("%.3f", speed) wird vermutlich nicht runden, daher würde ich etwas in der Art
int val = (int)((speed*1000)+0.5)
und dann mit format("%d,%03d m/s", val/1000, val%1000)
das Ergebnis ausgeben.

Antworten
Sam Browder
  • Forum-Beiträge: 236

02.12.2012, 19:39:44 via Website

Könntest du das bitte genauer erklären - damit ich es verstehe :(
Und was mache ich mit dem String? Wie sieht das Ganze aus, wenn ich km/h ausrechnen muss und die o. g. Variable "speed" als Ausgangswert benutzen will (double speed_kmh = speed*3.6;)?
Danke im Voraus!

Antworten
Gelöschter Account
  • Forum-Beiträge: 281

02.12.2012, 20:07:47 via Website

Mal angenommen, du willst nur noch den Speed in km/h entsprechend gerundet ausgeben, sähe das ganze am besten so aus

1float speed = location.getSpeed();
2
3// Umrechnen m/s -> km/h
4float speed_in_kmh = speed * 3.6;
5
6// Runden des Wertes
7speed_in_kmh = Math.round( speed_in_kmh * 1000.0f ) / 1000.0f ;
8
9// Ausgeben
10DecimalFormat decimalFormat = new DecimalFormat("0.000");
11textField.setText( decimalFormat.format(speed_in_kmh);

Antworten
Sam Browder
  • Forum-Beiträge: 236

02.12.2012, 20:11:21 via Website

JA!!! Ich hab`s kapiert! :grin:
Vielen Dank!

Antworten
Gelöschter Account
  • Forum-Beiträge: 281

02.12.2012, 20:46:08 via Website

Schön. Du solltest vielleicht noch im Sinne der performance darüber nachdenken, die Erzeugung des DecimalFormat-Objektes nicht jedes Mal zu machen, einen nur einmal beim Start der Activity.

Antworten
Sam Browder
  • Forum-Beiträge: 236

02.12.2012, 20:48:12 via Website

Ja, ist eine gute Idee! Danke! :)

Antworten
San Blarnoi
  • Forum-Beiträge: 2.545

03.12.2012, 10:01:59 via Website

Divisionen bei float verschlechtern das Ergebnis (im Sinne von Rundungsfehlern), daher würde ich das wenn möglich vermeiden.

Den String verwendest du als Parameter für dein "textField.setText"

Antworten
Gelöschter Account
  • Forum-Beiträge: 281

03.12.2012, 10:11:47 via Website

Stimmt grundsätzlich - aber bei der Datenquelle wohl zu verschmerzen ;-)

Antworten
San Blarnoi
  • Forum-Beiträge: 2.545

03.12.2012, 11:09:50 via Website

Ich hab mich eh gefragt, wozu er bei km/h drei Nachkommastellen benötigt, aber vielleicht ist das ja Teil eines Physik-Projektes (wobei man dort wohl bei m/s geblieben wäre) ;-)

Antworten
Sam Browder
  • Forum-Beiträge: 236

03.12.2012, 11:48:39 via Website

Hi!
Ich hab mich eh gefragt, wozu er bei km/h drei Nachkommastellen benötigt
Also ein km hat 1000m und ich will die Geschwindigkeit für mich so genau, wie Möglich haben. :) Damit kommen wir zu der Sache mit den Rudnugsfehlern: wie kommen denn diese zu Stande, und wie sind diese zu vermeiden?
Was den String angeht, habe ich einen anderen String gemeint. Die Variable für Geschwindigkeit ist ja in diesem Fall schon vorhanden ("speed_in_kmh"), die dann mit "...setText(....);" ausgeben wird.
Ich habe Mal eine andere Frage...
Ich habe heute das Ergebnis getestet (mit dem Auto), und habe herausgefunden, dass "updates" bei der Errechnung der aktuellen Geschwindigkeit völlig durcheinander sind. Wenn ich beschleunige, wird die neue Geschwindigkeit ca. alle 2 Sekunden angezeigt (aktualisiert). Wenn ich die Geschwindigkeit aber drossele, bzw. bremse - bleibt die Anzeige bei ca. 16 - 19 km/h kleben, auch wenn ich schon längst an der Ampel stehe. Erst nach ca. 10 Sekunden wird 0 km/h angezeigt. Und jetzt bin schon längst zurück, und die Anzeige zeigt immer noch 5,184km/h an :(. Wie kann ich es den so programmieren, dass die Anzeige min. 3 Mal pro Sekunde (Handler 300) updatet. Ich kenne zwar den Handler, und weiss, wie man diesen programmiert, aber bin mir nicht sicher, ob diese Lösung hier die richtige wäre, und auch an welche Stelle ich diesen hier Setzen muss. HAT SICH ERLEDIGT - ICH HABE DAS PROBLEM SELBST GELÖST!
Aber was ist mit der Ungenauigkeiten bei der Rechnung???
Danke im Voraus!

— geändert am 03.12.2012, 13:22:07

Antworten
San Blarnoi
  • Forum-Beiträge: 2.545

03.12.2012, 13:32:23 via Website

Damit kommen wir zu der Sache mit den Rudnugsfehlern: wie kommen denn diese zu Stande
Um mir (und dir) einen Ausflug in die Numerik zu ersparen sei verkürzend gesagt, das dies an der Art liegt, wie float/double intern gespeichert werden und das dies wiederum einem Kompromiss an die Performance geschuldet ist.

und wie sind diese zu vermeiden?
Wenn du keine Sprache benutzen kannst, die dafür ausgelegt ist (Fortran, Pascal SC, um mal zwei zu nennen), kannst du das nur vermeiden, wenn du keine floats benutzt, double wo unbedingt erforderlich und ansonsten bei Ganzzahlen bleibst;
in deinem Beispiel erhältst du einen float, dagegen kannst du nichts tun (ich würde da schon eine double Variable verwenden); die Multiplikation mit 3.6 ist ebenfalls nur mit erheblichem Aufwand vermeidbar, aber danach kannst du alles mit int machen (wie ich es im ersten Post vorgemacht habe)

Was den String angeht, habe ich einen anderen String gemeint. Die Variable für Geschwindigkeit ist ja in diesem Fall schon vorhanden ("speed_in_kmh")
Den gab es aber in deinem ersten Post (worauf sich mein erster Kommentar bezog) noch gar nicht.

Antworten
Sam Browder
  • Forum-Beiträge: 236

03.12.2012, 13:37:19 via Website

Also doch "double". Das hatte ich ja auch am Anfang stehen. Dann habe ich es auf "float" geändert :(
Dann ist ja alles in Ordnung :)
Danke für die Hilfe!

Antworten