# float/double Anzahl Nachkommastellen ermitteln



## Max Matti (12. Mrz 2011)

Hi,

Ich brauche gerade für mein Projekt eine Funktion, die die Anzahl der Nachkommastellen von einer Variable (float oder double) ermittelt, d.h.:

0,5 ->1
11,003 ->3
0,000 000 004 -> 9

Gibt es das in der Math-Klasse (alleine hab ichs nicht gefunden) oder muss ich das selber schreiben, wenn ja wie?

lg
Max


----------



## Runtime (12. Mrz 2011)

Musst du selber schreiben:

```
1. Modulo mit 1
2. Schleife mit int i = Anzahl Schleifendurchläufe
3. int wert anlegen mit Wert Math.pow(10, i) * floatWert
4. testen, ob wert == floatWert ist, wenn ja, dann Schleife abbrechen/beenden
Anzahl Nachkommastellen = i
```


----------



## XHelp (12. Mrz 2011)

Oder zu einem String machen und nach dem Komma splitten.
Musst nur aufpassen, dass der Wert nicht sowas wie 3.2E-20 ist. Also da vllt mit dem NumberFormat umwandeln und nicht einfach toString.


----------



## kirax (12. Mrz 2011)

Runtime hat gesagt.:


> Musst du selber schreiben:
> 
> ```
> 1. Modulo mit 1
> ...



Das geht schief, sobald es mehr als ~10 Nachkommastellen werden, da du dann an die Grenze von 2^31-1 stößt.
Und doubles können seehr viele Nachkommastellen haben.

Ich denke es ist sinnvoller, das über einen String zu lösen:

```
public int stellen(double d) {
  String s = Double.toString(d);
  s = s.substring(s.indexOf(",") + 1);
  return s.length();
}
```



XHelp hat gesagt.:


> Oder zu einem String machen und nach dem Komma splitten.
> Musst nur aufpassen, dass der Wert nicht sowas wie 3.2E-20 ist. Also da vllt mit dem NumberFormat umwandeln und nicht einfach toString.


Da war wohl jemand schneller. Den Test auf die Darstellung muss man natürlich machen.


----------



## Max Matti (12. Mrz 2011)

Hi,

Erstmal danke, dass so schnell so viele Antworten kamen.
Also übernehme ich den Quelltext von kirax und ersetze toString durch was?
(Das Programm, zu dem das gehört, rechnet mit einiger Genauigkeit, daher kann es auch sein, dass hinten e-* steht)

lg
Max


----------



## XHelp (12. Mrz 2011)

Du ersetzt es durch den Einsatz von NumberFormat. Wie du es verwendest steht auch schon in der API beschrieben.


----------



## kirax (13. Mrz 2011)

Was du auch noch checken müsstest ist der decimal separator. Im Deutschen ist das ein Komma, im Englischen schon ein Punkt.
Hab das noch nie gemacht, aber da gibts auch irgendwie ne Möglichkeit auf unterschiedliche locals zu reagieren.


----------



## XHelp (13. Mrz 2011)

kirax hat gesagt.:


> Hab das noch nie gemacht, aber da gibts auch irgendwie ne Möglichkeit auf unterschiedliche locals zu reagieren.


Jo, der NumberFormat kann das


----------



## Ark (13. Mrz 2011)

Wie genau brauchst du denn die Nachkommastellen? Und: Wie viele Nachkommastellen hat 1.0/3.0? Wenn es um Genauigkeit geht, sollte wohl eher BigDecimal herhalten (oder man zählt die signifikanten Stellen selbst mit).

Ark


----------



## kirax (13. Mrz 2011)

Ark hat gesagt.:


> Wie viele Nachkommastellen hat 1.0/3.0?



Das Problem hat man mit allen periodischen Zahlen.
Und Fließkommazahlen unterliegen sowieso einer Ungenauigkeit, die wahrscheinlich eh höher ist als die Toleranz um die es bei dem Problem geht


----------



## StrikeTom (13. Mrz 2011)

Auch noch eine möglichkeit wäre:

```
float a = (float) 2.2789;
		
		String[] asplit =  Float.toString(a).split("\\.");
		int nachkomma = asplit[1].length();
		System.out.println(nachkomma);
```


----------



## XHelp (13. Mrz 2011)

StrikeTom hat gesagt.:


> Auch noch eine möglichkeit wäre:



Die hatten wird schon. Es geht ja auch in den letzten Beiträgen um diese Idee und was passiert, wenn es 
	
	
	
	





```
float a = (float) 2.7E-5
```
 heißt (warum auch immer der Umweg über float)


----------



## nrg (13. Mrz 2011)

kirax hat gesagt.:


> Was du auch noch checken müsstest ist der decimal separator. Im Deutschen ist das ein Komma, im Englischen schon ein Punkt.
> Hab das noch nie gemacht, aber da gibts auch irgendwie ne Möglichkeit auf unterschiedliche locals zu reagieren.




```
DecimalFormatSymbols.getInstance().getDecimalSeparator()
```


----------



## Max Matti (13. Mrz 2011)

kirax hat gesagt.:


> Das Problem hat man mit allen periodischen Zahlen.
> Und Fließkommazahlen unterliegen sowieso einer Ungenauigkeit, die wahrscheinlich eh höher ist als die Toleranz um die es bei dem Problem geht



Naja, es gibt mehrere Möglichkeiten, den Datentyp anzulegen, den ich aus dem float/double ziehen will: einmal über 2 Zahlen, die danach von der Funktion Dividiert werden [abc(5, 3) => 1u2/3] oder über ein float/double, was halt etwas ungenau ist, wenn man etwas genauer rechnen will, nimmt man halt die andere Möglichkeit...


----------



## Max Matti (25. Mrz 2011)

Hab es jetzt so gelöst:


```
/*
	 * Constructs a Fraction out of a double.
	 * Example: 0.333 -> 333/1000
	 */
	public Fraction(double zahl) {
		for (int i = 1; true; i *= 10) {
			if ((double)(zahl*i) == Math.floor(zahl*i)) {
				this.numerator = (int)(zahl*i);
				this.denominator = i;
				break;
			}
		}
		
	}
```


----------



## XHelp (25. Mrz 2011)

Und was kriegst du bei 
	
	
	
	





```
new Fraction(1/3d)
```
 als Ergebnis?


----------



## Max Matti (1. Apr 2011)

Hi,

ich glaub du meinst ohne d, ich teste das mal, moment...

Edit: Gerade getestet, => 0 aber für solche Fälle hab ich:

```
/*
	 * Constructs a Fraction with an long numerator and an long denominator.
	 * TODO: For constructing a Random Fraction use Fraction().
	 */
	public Fraction(long numerator, long denominator) {
		this.numerator = numerator;
		if (denominator == 0) {
			throw (new ArithmeticException("Denominator can't be 0."));
		}
		this.denominator = denominator;
	}
```

(und das gleiche noch mit ints)


----------



## XHelp (1. Apr 2011)

Nein, ich meine schon was was ich geschrieben habe... mit 
	
	
	
	





```
d
```


----------



## Max Matti (1. Apr 2011)

-510164992 / -1530494976
gekürzt 1/3.


----------

