Math.round

mattrock

Mitglied
Hi,
ich habe folgenden Code:

Java:
import java.util.ArrayList;
import a1.CartItem;

public class ShoppingCart {
	
	//Konstruktor= Initialisiert den Zustand eines neuen Objekts.
	public ShoppingCart(){
		myShoppingCart = new ArrayList<Object>(0);
	}
	
	//speichern
	ArrayList<Object> myShoppingCart;
	
	public void add(CartItem item){
		myShoppingCart.add(item);		
	}
		
	public double getTotalCost(){
		double total=0.0;
		for(int i=0;i<myShoppingCart.size();i++){
			CartItem test = (CartItem) myShoppingCart.get(i);
			total += test.pricePerUnit * test.quantity;
		}
		return total;
	}
	
	public String toString(){
		String _return = "";
		double totalcost=0;
		for(int i=0;i<myShoppingCart.size();i++){
			_return = _return+"  "+myShoppingCart.get(i)+"\n";
		}
		totalcost += getTotalCost();
		return  _return+"\nSumme:\t\t\t\t\t"+totalcost ;											
		
	}
			

}

Nun möchte ich das totalcost auf 2 Stellen hinter dem Komma gerundet wird. Es müsste 42,83 eigentlich raus kommen.
Aber wenn ich Math.round anwende kommt 42 raus. Warum??
Java:
totalcost += getTotalCost();
		return  _return+"\nSumme:\t\t\t\t\t"+Math.round(totalcost*100)/100 ;

Oder habe ich da einen großen Denkfehler

Dank schon mal im voraus.
 
Zuletzt bearbeitet von einem Moderator:
Wenn du in Java eine Ganzzahl durch eine andere Ganzzahl teilst, dann kommt auch wieder eine Ganzzahl raus - selbst wenn das Ergebnis eine Fließkommazahl wäre. Caste eine Zahl vor der Berechnung in eine Fließkommazahl und du erhältst das richtige Ergebnis.
Code:
5/2 => 2
(float)5/2 => 2.5
 
also
Java:
double totalcost=0.0;
klappt nicht. Da verändert sich rein gar nichts.

Wenn ich das Math.round weg lasse kommt Summe: 42.830000000000001 raus.
Will nur das nur 42,83 stehen bleibt.

Irgendwie klappt das alles nicht. Auch nicht mit den casten.
 
Zuletzt bearbeitet:
Teil mal durch "100." statt durch "100". Damit wird das Ergebnis auch eine Fließkommazahl und kein integer.
 
Wenn es dir nur um die formatierte Ausgabe geht, benutze lieber einen Formatter, z.B.

Java:
System.out.printf("%3.2f", totalcost)
 
Du solltest beim Runden von Negativen Zahlen aufpassen. Math.round nimmt es da nicht so ganz genau.

[Java]
public static void main(String[] args) {

double a = 2.4;
double aa = -2.4;

double b = 2.5;
double bb = -2.5;

double c = 2.6;
double cc = -2.6;

System.out.println(" "+ a + " = " + Math.round(a));
System.out.println("" + aa + " = " + Math.round(aa));
System.out.println(" "+ b + " = " + Math.round(b));
System.out.println("" + bb + " = " + Math.round(bb));
System.out.println(" "+ c + " = " + Math.round(c));
System.out.println("" + cc + " = " + Math.round(cc));
}
[/Java]

[Java]
2.4 = 2
-2.4 = -2
2.5 = 3
-2.5 = -2 // falsch, im Negativen wird bei ",5" von der 0 weg gerundet. -3 ist hier Richtig.
2.6 = 3
-2.6 = -3
[/Java]
 
Zuletzt bearbeitet:
[..] Es wurde doch völlig korrekt ab 0.5 aufgerundet,[..]
Ark
Ersetze aufrunden durch [von der 0 weg] und abrunden durch [zur 0 hin].

-x.0 / -x.1 / -x.2 / -x.3 / -x.4 abgerundet [zur 0 hin] bei
-x.5 / -x.6 / -x.7 / -x.8 / -x.9 aufgerundet [von der 0 weg].

Oder anders ausgedrückt, wenn du das Vorzeichen ausklammerst, sollte das SELBE Ergebnis zu stande kommen.
 
Zuletzt bearbeitet:
nana, nicht so feste mit dieser Bewertung, wo ist das bitte eindeutig definiert?
wieviele Menschen würden wohl (ohne die Definition gerade nachgelesen zu haben) so oder so entscheiden?
meiner spontanen Einschätzung nach ist die Java-Umsetzung auch eher ungewöhnlich,

Excel macht es z.B. andersherum, auch wenn das vielleicht nicht zählen muss,
genausowenig dann folgendes Dokument von Microsoft
How To Implement Custom Rounding Procedures
Arithmetic Rounding
When rounding always down or up, the resulting number is not necessarily the closest to the original number. For example, if you round 1.9 down to 1, the difference is a lot larger than if you round it up to 2. It is easy to see that numbers from 1.6 to 2.4 should be rounded to 2.

However, what about 1.5, which is equidistant between 1 and 2? By convention, the half-way number is rounded up.

You can implement rounding half-way numbers in a symmetric fashion, such that -.5 is rounded down to -1, or in an asymmetric fashion, where -.5 is rounded up to 0.

The following functions provide symmetric arithmetic rounding:
The Excel Round() spreadsheet function.
The SQL Server Round() function can do symmetric arithmetic rounding.

The following function provide asymmetric arithmetic rounding:
The Round() method of the Java Math library.

edit:
auch Oracle-DB rundet symmetrisch
 
Zuletzt bearbeitet von einem Moderator:
@hansmueller
nicht wirklich, denn die Implementierung ist
Java:
    public static long round(double a) {
	return (long)floor(a + 0.5d);
    }

RoundingMode ist aber ein tolles Stichwort, was ich vorher schon selber gerade verkünden wollte,
wenn ich das nicht ganz falsch sehe, gibt es dort keine Möglichkeit, die asymmetrische Rundung durchzuführen!
symmetrisch ist HALF_UP, der Standard

damit stellt sich Math.round() gegen die ausgereifteren Klassen, auch wenn ich die programmatische Umsetzung sympatisch finde,
habe ich glaube ich auch irgendwo als Code stehen 😉 (+0.5, dann floor)
 
Zuletzt bearbeitet von einem Moderator:
@ SlaterB Vertauschst du da nicht asymmetrisch und symmetrisch?

You can implement rounding half-way numbers in a symmetric fashion, such that -.5 is rounded down to -1, or in an asymmetric fashion, where -.5 is rounded up to 0.

Die Asymetrische Rundung ist doch implementiert?! Oder versteh ich da was falsch gerade.
 
inwiefern vertausche ich das? ich treffe ja viele Aussagen dazu, meiner Ansicht nach alles konsistent

asymmetrisch:
- Math.round()
- in RoundingMode nicht verfügbar
- mathematisch vielleicht sauberer, nach Menschenverstand aber eher unerwartet/ unhandlich

symmetrisch:
- Excel
- Oracle
- RoundingMode HALF_UP
 
Das mathematische Runden wird auch Symmetrisches Runden genannt.

Ich habe den begriff asymmetrisch jetzt nicht direkt gefunden, aber meiner Meinung müsste das doch HALF_DOWN sein, wenn die Definition stimmt:

or in an asymmetric fashion, where -.5 is rounded up to 0.
 
Nach Wikipedia ist symetrisch runden weder fix nach oben noch fix nach unten, sondern es wird auf die nächste gerade Zahl gerundet.

z.b

2.5 wird zu 2 und 3.5 wird zu 4
ebenfalls im negativen

-2.5 wird zu -2 und -3.5 wird zu 4
Rundung ? Wikipedia
 
ich beziehe mich auf den von mir zitierten Artikel, wenn es andere Definitionen für die Begriffe wie 'symmetrisch' gibt, dann ist das natürlich unglücklich

@Blakh
HALF_DOWN rundet im positiven Bereich 2.5 auf 2, ist also komplett was anderes
@AmunRa
dass .5 mal auf, mal abgerundet wird, ist zwar statisch praktisch aber ebenso relativ fern der Diskussion was anderes
 
Ich bin verwirrt. Nach deiner Definition ist asymmetrisch, wenn bei -.5 auf 0 gerundet wird.


Aber das macht doch genau derRoundingMode HALF_UP.

Edit. Ne macht er nicht 😉.

Nochmal Edit: CEILING ist doch aber assymetrisch und FLOOR, genauso wie UP und DOWN.

Versteh ich den Begriff assymetrisch hier falsch?
 
Zuletzt bearbeitet:
es geht seit Shulyn vs xehpuk, wo ich mich einfach eingemischt habe, darum, ob -1.5 auf -1 oder -2 gerundet wird,
wie .6 bis .4 gerundet wird ist klar, .5 im positiven Bereich ebenso, nur .5 im Negativen fraglich,

CEILING, FLOOR, UP, DOWN, sind unerheblich, HALF_DOWN genauso (rundet .5 im postivien ab)
HALF_EVEN = abwechseln mal auf und mal abrunden ist für sich nett, aber zu kompliziert, rundet ja teils auch .5 im positiven Bereich ab

wenn -1.5 entweder auf -1 oder auf -2 gerundet wird, dann sind das genau zwei Varianten,
meine Benennung richtet sich nach meinem Zitat von 11:47, ist ja auch egal,
Math.round() macht es soundso, andersrum ist die Alternative
 
Zuletzt bearbeitet von einem Moderator:
Hmm, ich habe auch nicht gedacht, dass man da so viele "gängige" Verfahren hat.

Ich sehe zumindest das asymmetrische Runden per Math.round() als Standard in der Mathematik. Interessant finde ich auch die Bemerkung zu ROUND_HALF_UP im JavaDoc:
Code:
Note that this is the rounding mode that most of us were taught in grade school.
Ich kann mich nicht daran erinnern, dass uns damals explizit etwas zum Runden von negativen Dezimalbrüchen mitgeteilt wurde, was dann ja implizit für die Asymmetrie steht ("auf die nächstgrößere Zahl"). Aber das ist dann wohl auch von Staat zu Staat, von Land zu Land, von Schule zu Schule und von Lehrer zu Lehrer unterschiedlich. 😛

Per Google lässt sich auch nicht so einfach Fachliteratur dazu finden. Vielleicht frag ich meinen Mathe-Prof demnächst mal danach.
 
.5 wird "auf die nächstgrößere Zahl" gerundet genau wie * 3 eine größere Zahl ergibt, dabei wird nur über den Betrag einer Zahl nachgedacht,
nicht einbezogen das -9 als Dreifaches von -3 eigentlich eine kleinere Zahl ergibt 😉


so richtig definiert wurde das bei uns auch nie, aber -2.5 gerundet auf -2, das wäre mir in der Schule oder im Studium in Erinnerung geblieben
 
Da kommt es dann darauf an, wie formal korrekt man sich ausdrückt. Wie du bereits angedeutet hast, dass
Code:
3x >= x
bzw.
Code:
3x > x
falsch ist, solange man sich nicht auf die natürlichen oder positiv reellen Zahlen (im zweiten Fall ohne 0) beschränkt.

Aber wenn man dann sagt, "auf die nächstgrößere Ziffer", dann ist es symmetrisches Runden. [Wobei: Wenn man von 9 auf 10 rundet … 😳]
 
Zuletzt bearbeitet:
Zum Thema: (nach Wikipedia)
Mathematische Rundung

Die Mathematische (auch geodätische oder unverzerrte) Rundung ist wie folgt definiert:[1]

1. Folgt auf die letzte beizubehaltende Ziffer eine 0, 1, 2, 3 oder 4, so wird abgerundet.
2. Folgt auf die letzte beizubehaltende Ziffer eine 9, 8, 7, 6 oder eine 5, gefolgt von weiteren Ziffern, die nicht alle null sind, so wird aufgerundet.
3. Folgt auf die letzte beizubehaltende Ziffer lediglich eine 5 (oder eine 5, auf die nur Nullen folgen), so wird derart gerundet, dass die letzte beizubehaltende Ziffer gerade wird.

Diese Art der Rundung wird in der Mathematik und Ingenieurswissenschaften verwendet. Sie ist im IEEE-754-Standard für das Rechnen mit binären Gleitkommazahlen in Computern vorgesehen. Weitere Namen für diese Art der Rundung sind Wissenschaftliches oder Symmetrisches Runden[2]; in englischsprachiger Literatur Round to Even oder Banker's Rounding[3].

Beispiele (Rundung auf eine Nachkommastelle):

* 2,2499 ≈ 2,2 (nach Regel 1)
* 2,2501 ≈ 2,3 (nach Regel 2)
* 2,2500 ≈ 2,2 (nach Regel 3 zur geraden Ziffer hin gerundet)
* 2,3500 ≈ 2,4 (nach Regel 3 zur geraden Ziffer hin gerundet)

Kaufmännisches und unverzerrtes mathematisches Runden unterscheiden sich nur darin, wohin eine Zahl genau in der Mitte zwischen zwei Zahlen mit der gewählten Anzahl von Dezimalziffern gerundet wird.

Das kaufmännische Runden erzeugt kleine systematische Fehler, da das Aufrunden um 0,5 vorkommt, das Abrunden um 0,5 jedoch nie; das kann Statistiken geringfügig verzerren.

Die mathematisch unverzerrte Rundung (englisch round to even) rundet von der genauen Mitte zwischen zwei Ziffern immer zur nächsten geraden Ziffer auf oder ab. Dadurch wird im Mittel genauso oft auf- wie abgerundet und der oben angesprochene systematische Fehler vermieden.
 
Zuletzt bearbeitet:
-.5, nicht .5. 😉

* 2,2500 ≈ 2,2 (nach Regel 3 zur geraden Ziffer hin gerundet)
* 2,3500 ≈ 2,4 (nach Regel 3 zur geraden Ziffer hin gerundet)
Und wie sieht es dann bei 2,3000 aus? Abgerundet (Regel 1) hieße dann wohl, dass es einfach so bleibt.
 
Zuletzt bearbeitet:
Hatte es schon editiert 😉

@round():
public static long round(double a)

Returns the closest long to the argument. The result is rounded to an integer by adding 1/2, taking the floor of the result, and casting the result to type long. In other words, the result is equal to the value of the expression:

(long)Math.floor(a + 0.5d)
Also nicht symmetrisch gerundet.

Wobei ich vor allem das hier interessant finde:
Das kaufmännische Runden erzeugt kleine systematische Fehler, da das Aufrunden um 0,5 vorkommt, das Abrunden um 0,5 jedoch nie; das kann Statistiken geringfügig verzerren.

€:
Und wie sieht es dann bei 2,3000 aus?
garkein problem, da keine 5 enthalten ist wird natürlich abgerundet auf 2,0. Auf eine Stelle hinterm Komma runden macht ja bei 0 ohnehin keinen Sinn, da nichts zu tun ist außer Abschneiden.
 
[..]
Ich sehe zumindest das asymmetrische Runden per Math.round() als Standard in der Mathematik. Interessant finde ich auch die Bemerkung zu ROUND_HALF_UP im JavaDoc:[..]

Sehe ich nicht so. Gehen wir mal von einem solchen fall aus :

-1.5 = (-)*1.5 / Mathematisch sollte das passen.

Jetzt runden wir alle Zahlen mit math.round().

-1 = (-)*2

-1 = -2

Irgendwie kommt das so garnicht hin. :rtfm:
Wie SlaterB schon gezeigt hat, ist die umsetzung von Math.round() sehr schön, aber erzeugt falsche Ergebnisse beim Runden von Negativen Zahlen (-x.5). (Flasch Mathematisch betrachtet)

Java:
    public static long round(double a) {
        return (a < 0 ? -1 : 1) * (long)Math.floor(Math.abs(a) + 0.5d);
    }
So würde es passen.
 
Ich meinte natürlich auf die erste Nachkommastelle runden, aber da trifft wohl einfach Regel 1 zu, dass abgerundet, also abgeschnitten wird (in dem Fall die drei Nullen) => 2,3.

Wobei das mit der statistischen Verzerrtheit auch etwas hat …

-1.5 = (-)*1.5 / Mathematisch sollte das passen.

Jetzt runden wir alle Zahlen mit math.round().

-1 = (-)*2

-1 = -2

Irgendwie kommt das so garnicht hin. :rtfm:
Das sind keine mathematischen Ausdrücke, die du da hast. Was soll "(-)*1.5" sein? Etwa "(-1)*1.5"? Runden ist aber nicht multiplikativ, von daher handelt es sich dort eh nicht um Äquivalenzumformungen.
 

Neue Themen


Zurück
Oben