# Kommastellen aus float extrahieren



## spacegaier (5. Sep 2007)

Hallo zusammen,

gibt es eine einfache Möglichkeit aus einem float die Kommastellen zu extrahieren. Das was vor dem Komma steht interessiert mich nicht.

Oder muss ich den float in einen String konvertieren und dann da so rumpfguschen, dass ich von dem String die hinteren beiden chars erhalte und diese dann wieder in einen int konvertieren?

Grüße - spacegaier


----------



## Wildcard (5. Sep 2007)

Selbst parsen oder DecimalFormat, das sind die beiden naheliegendsten Möglichkeiten.


----------



## spacegaier (5. Sep 2007)

Meinst du mit selbst parsen meine oben genannte Variante mit dem String?


----------



## Wildcard (5. Sep 2007)

Ja, auch wenn mir schleierhaft ist wie du auf die 'hinteren beiden chars' kommst. Warum sollte ein float immer 2 Nachkommastellen haben?


----------



## Wildcard (5. Sep 2007)

Vielleicht noch zur Erklärung warum der von dir geforderte 'einfache' Weg eben nicht so einfach ist:
Die Zahl liegt intern in einer IEEE ähnlichen Darstellung vor.
Das bedeutet am Anfang kommt ein MSB, dann kommt ein 8 bit langer Exponent der um einen Offset von (i.d.R. 127 verschoben wurde) gefolgt von 23 Bit Mantisse, die vorher auch noch normalisiert wird.
Daraus nun die dezimalen Nachkommastellen zu berechnen ist so ganz trivial also nicht (zumindest wenn man bedenkt das die einzelnen Längen von der Prozessorarchitektur abhängen)  :wink:


----------



## spacegaier (5. Sep 2007)

Meine floats haben immer nur zwei Nachkommastellen (werden aus einer Datei eingelesen).


----------



## Wildcard (5. Sep 2007)

Wie bildest du 0,3 auf ein Binärformat ab?

```
Zb 0,3:
0*1
0*0,5
1*0,25
0*0,125
0*0,0625
1*0,03125
....

-> 0,01001...
```


----------



## Kim Stebel (6. Sep 2007)

@wildcard: Möchtest du spacegaier verwirren oder ihm helfen? Wie floats oder doubles intern dargestellt werden ist doch für diese Frage gar nicht von Belang. :noe: 
@spacegaier: meinst du sowas?

```
double d = 5.33;
int i = (int)d;
d = d - (double)i;
System.out.println(d);
```
Ausgabe: 0.33........


----------



## Murray (6. Sep 2007)

Kim Stebel hat gesagt.:
			
		

> @wildcard: Möchtest du spacegaier verwirren oder ihm helfen? Wie floats oder doubles intern dargestellt werden ist doch für diese Frage gar nicht von Belang. :noe:
> @spacegaier: meinst du sowas?
> 
> ```
> ...



Mit d = 5.33 gibt das bei mir 0.33000000000000007, mit d = 5.30 bekomme ich 0.2999999999999998. Das Problem besteht wie von Wildcard beschrieben in der internen Darstellung von floats und doubles. Man müsste also auf jeden Fall das Ergebnis noch auf zwei Stellen runden (und nicht einfach abschneiden).

Wenn es nur darum geht, aus einer Textdatei Zahlen mit genau zwei Nachkommastellen einzulesen, dann wird es wohl besser sein, das Problem auf der String-Ebene zu lösen; aus der Datei sollte man die Zahlen also nicht als double oder float, sondern einfach als String lesen. Dann kann man z.B. mit String#indexOf die Position des Dezimaltrenners bestimmen und mit String#substring den Teil rechts davon isolieren. Diesen Teilstring kann man dann mit Integer#parseInt in eine Ganzzahl wandeln, die dann den Wert der Nachkommastellen haben.


----------



## Kim Stebel (6. Sep 2007)

@ wildcard: das muss man selbstverständlich noch auf 2 stellen runden....die aus der internen Darstellung resultierenden Rundungsfehler werden sich wohl kaum auf die 2te Nachkommastelle auswirken


----------



## Murray (6. Sep 2007)

Kim Stebel hat gesagt.:
			
		

> die aus der internen Darstellung resultierenden Rundungsfehler werden sich wohl kaum auf die 2te Nachkommastelle auswirken


Das hängt von Anteil vor dem Komma ab: wenn die Zahl groß genug wird, dann kann sich die Ungenauigkeit durchaus dort auswirken (ggfs. sogar schon im Bereich vor dem Komma). 

Test doch mal d = 3333333333.30 oder d = 3333333333.0


----------



## Kim Stebel (6. Sep 2007)

du meinst sein Unternehmen hantiert mit solchen Beträgen und kann sich keinen Programmierer leisten? 
Spaß bei Seite...falls es sich um Geldbeträge handelt, ist natürlich int die bessere Wahl.


----------



## Marco13 (6. Sep 2007)

int i = (int)(f * 100) % 100;


----------



## Murray (6. Sep 2007)

Marco13 hat gesagt.:
			
		

> int i = (int)(f * 100) % 100;


Dass man so auf zwei Stellen runden kann, ist klar; das Problem der Ungenauigkeit durch die begrenzte Auflösung löst man damit aber nicht.


----------

