2010-05-26 1 views
15

Ich versuche, diese einfache Berechnung in einer Java-Anwendung:Einfache Aufteilung in Java - ist das ein Fehler oder eine Funktion?

System.out.println("b=" + (1 - 7/10)); 

Offensichtlich ich b=0.3 für die Ausgabe will, aber hier ist was ich b=1 bekommen.

Was ?! Warum passiert das?

Wenn ich machen:

System.out.println("b=" + (1 - 0.7)); 

ich das richtige Ergebnis zu erhalten, die b=0.3 ist.

Was läuft hier falsch?

Antwort

54

Sie verwenden Ganzzahldivision.

Versuchen Sie stattdessen 7.0/10.

+23

Ich füge hinzu, dass dies kein Fehler ist. Es ist eine Funktion. ':]' –

+8

weder Bug noch Feature - es funktioniert wie geplant. –

+1

Wenn Sie mit Variablen arbeiten, können Sie einfach jede von ihnen in Float umwandeln. a = 1; b = 2; a/b = 0; (float) a/b = 0,5; a/(float) b = 0,5; – Azee

24

Sie haben Integer im Ausdruck 7/10 verwendet, und Integer 7 dividiert durch Integer 10 ist Null.

Was Sie erwarten, ist Gleitkomma Division. Jede der folgenden würde bewerten, wie Sie erwartet:

7.0/10 
7/10.0 
7.0/10.0 
7/(double) 10 
1

Ich finde Brief Identifikatoren mehr lesbar sein und mehr anzeigt geparsten Typ:

1 - 7f/10 
1 - 7/10f 

oder:

1 - 7d/10 
1 - 7/10d 
8

Bitte nimm das nicht als Antwort auf die Frage. Es ist nicht, aber ein Rat in Bezug auf die Ausnutzung der Differenz von Int und Float. Ich hätte dies unter einen Kommentar gestellt, außer dass die Antwortbox mir erlaubt, diesen Kommentar zu formatieren.

Diese Funktion wurde in jeder respektablen Programmiersprache seit den Tagen von Fortran (oder früher) verwendet - ich muss gestehen, ich war einmal ein Fortran und Cobol Lochkarten-Programmierer.

Als Beispiel ergibt eine ganzzahlige Division von 10/3 den ganzzahligen Wert 3, da eine ganze Zahl keine Möglichkeit bietet, das fraktionale Residuum .3333 .. zu halten.

Eine der Möglichkeiten, die wir (alte Zeit alte Programmierer) diese Funktion verwendet haben, ist die Schleifensteuerung.

Lassen Sie uns sagen, wir wollen eine Reihe von 1000-Strings drucken, aber wir wollen einen Zeilenumbruch nach jedem 15. Zeichenfolge einzufügen, einige prettyfying Zeichen am Ende der Zeile und am Anfang der nächsten Zeile einzufügen. Wir nutzen dies, da die Ganzzahl k die Position einer Zeichenkette in diesem Array ist.

int(k/15)*15 == k 

ist nur wahr, wenn k durch 15 teilbar ist, ein Auftreten bei einer Frequenz von jeder 15. Zelle. Das ist vergleichbar mit dem, was mein Freund über die tote Uhr seines Großvaters gesagt hat, zweimal am Tag genau zu sein.

int(1/15) = 0 -> int(1/15)*15 = 0 
int(2/15) = 0 -> int(2/15)*15 = 0 
... 
int(14/15) = 0 -> int(14/15)*15 = 0 
int(15/15) = 1 -> int(15/15)*15 = 15 

int(16/15) = 1 -> int(16/15)*15 = 15 
int(17/15) = 1 -> int(17/15)*15 = 15 
... 
int(29/15) = 1 -> int(29/15)*15 = 15 
int(30/15) = 2 -> int(30/15)*15 = 30 

Daher ist die Schleife,

leftPrettyfy(); 
for(int k=0; k<sa.length; k++){ 
    print(sa[k]); 
    int z = k + 1; 
    if ((z/15)*15 == z){ 
    rightPrettyfy(); 
    leftPrettyfy(); 
    } 
} 

durch k in einer phantasievollen Art und Weise in der Schleife variiert wird, könnten wir einen dreieckigen Ausdruck

1 
2 3 
4 5 6 
7 8 9 10 
11 12 13 14 15 

drucken, dass nachzuweisen ist, wenn Sie betrachten dies als einen Fehler, dieser "Fehler" ist ein nützliches Feature, das wir aus keiner der verschiedenen Sprachen, die wir bisher verwendet haben, entfernen möchten.

+5

Stimmt etwas nicht mit 'k% 15 == 0'? – Corey

+0

Da mod (a, x) = a - (x * int (a/x)), glaube ich, liegt die Antwort darin, dass neben der Last, einen Argumentstapel wiederholt zu konstruieren, auch ein Code jmp zum Aufruf einer Modulo-Subroutine zählt dass die inline a == (x * int (a/x)) ist eine Operation effizienter als a - (x * int (a/x)) == 0 –

+0

Ich schrieb "Durch Variation k in einem phantasievollen In der Schleife könnten wir einen dreieckigen Ausdruck drucken ", für k == (k/L) * L. Es hätte sein sollen - "Indem wir L auf phantasievolle Weise in der Schleife variierten, konnten wir einen dreieckigen Ausdruck drucken." –

0

In meinem Fall ich tat dies:

double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1)); 

Statt der "richtigen":

double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1); 

Nehmen Sie Aufmerksamkeit mit den Klammern!

Verwandte Themen