Fomatierungszeichen %G für printf => Exponent beeinflussen

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Fomatierungszeichen %G für printf => Exponent beeinflussen

Beitrag von Bruno » Di Dez 06, 2011 3:16 pm

Hallo!

Ich muß sehr große float Werte mit möglichst großer Genauigkeit in ein 8-spaltiges Format "pressen".
Bitte keine Diskussion warum und weshalb: das Programm, das meine Daten anschließend liest will es so und ich kann das Programm nicht austauschen!

Nach einigen Experimenten habe ich mich für %G entschieden, weil erst bei recht großen Zahlen auf Exponentialdarstellung umgeschaltet wird.

Mein Problem ist, daß der Exponent immer zweistellig und mit Vorzeichen geschrieben wird: 1.23E+06, wobei mir 2 Stellen Genauigkeit flöten gehen.
Kann ich irgendwie die Darstellung des Exponenten beeinflußen, damit ich statt 1.23E+06 eine 1.2345E6 bekomme?
Ich habe jetzt schon ca. 2 h das I-Net befragt, aber nichts dazu finden können.

Ciao

Jürgen
"21" ist nur die halbe Wahrheit...

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von cloidnerux » Di Dez 06, 2011 3:23 pm

http://www.cplusplus.com/reference/clib ... io/printf/
Wie wäre es mit %e/%E?
(Hab 20s gegoogelt)
Redundanz macht wiederholen unnötig.
quod erat expectandum

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Bruno » Di Dez 06, 2011 4:08 pm

Hallo!

Das ich 2h gegoogelt habe hat seinen Grund:
Der Formatierer %e/E liefert immer Exponentialdarstellung. Da "große" Werte in manchen Fällen auch irgendwas im 100er oder 10er Bereich heißen kann (je nach Anwendungsfall) wäre es schön, wenn diese Zahlen im %f-Format ausgegeben werden. Da kann ich natürlich in einer if-Bedingung stecken, aber da ich eine Menge Werte so abfragen muß ist das recht aufwändig, daher G => nimmt %f oder %E je nach Größe des Wertes, siehe Beispiel.

Code: Alles auswählen

#include <stdio.h>
int main(){
float Klein=0.1234567;
float Gross=123456789;

printf("%%G    %G\n",Klein);
printf("%%G    %G\n",Gross);
printf("%%E    %E\n",Klein);
printf("%%E    %E\n",Gross);
}
Außerdem kann ich mit %e die Anzahl der Exponentenstellen auch nicht beeinflussen und darum gings mir ja und as habe ich in den 2h googeln nicht gefunden.Evt. bin ich ja blind, daher frage ich die Sehenden...

In FORTRAN konnte man die Ausgabe im E Format entsprechend formatieren: 1.23+E004, 1.23E04, 1.23E4, usw.

Ciao

Jürgen
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Xin » Di Dez 06, 2011 4:34 pm

Bruno hat geschrieben:Außerdem kann ich mit %e die Anzahl der Exponentenstellen auch nicht beeinflussen und darum gings mir ja und as habe ich in den 2h googeln nicht gefunden.Evt. bin ich ja blind, daher frage ich die Sehenden...

In FORTRAN konnte man die Ausgabe im E Format entsprechend formatieren: 1.23+E004, 1.23E04, 1.23E4, usw.
Ich denke, da wirst Du Dir selbst was schreiben müssen, die Exponentialdarstellung ist - glaube ich - nicht so gut zu konfigurieren. Du könntest Dir hier eine angepasste Version von printf() zaubern: printe(), in der Du den String mit sprintf() erzeugst und anschließend nochmal überarbeitest?

Das Problem ist mir allerdings auch noch nicht aufgekommen. Zahlen > E100 sollten imho auch auffallen, denn im Prinzip ist 1.2345678+E100 gleichbedeutend mit 'willkürliche Zahlenfolge ohne Bezug zur Berechnung'. Du kannst davon ausgehen, dass Zahlen in der Größenordnung einfach nur Datenschrott sind.

Ansonsten, @cloidnerux, warum in die Ferne googlen, wenn das Deutsche liegt so nah?
http://www.proggen.org/doku.php?id=c:li ... rmatstring
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von cloidnerux » Di Dez 06, 2011 5:21 pm

Ansonsten, @cloidnerux, warum in die Ferne googlen, wenn das Deutsche liegt so nah?
http://www.proggen.org/doku.php?id=c:li ... rmatstring
Sorry, aber ich bins gewohnt mit Strg+T nen neuen Tab aufzumachen und den Suchbegriff einzugeben.
Ich versuche mich aber zu bessern!
Der Formatierer %e/E liefert immer Exponentialdarstellung. Da "große" Werte in manchen Fällen auch irgendwas im 100er oder 10er Bereich heißen kann (je nach Anwendungsfall) wäre es schön, wenn diese Zahlen im %f-Format ausgegeben werden. Da kann ich natürlich in einer if-Bedingung stecken, aber da ich eine Menge Werte so abfragen muß ist das recht aufwändig, daher G => nimmt %f oder %E je nach Größe des Wertes, siehe Beispiel.
Die beste Annäherung an dein Problem nach oben genannter Quelle wäre folgendes Konstrukt:

Code: Alles auswählen

printf("%.5G", Groß);
=> 1.2346E+008 unter Windows 7 64-Bit
Redundanz macht wiederholen unnötig.
quod erat expectandum

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Bruno » Mi Dez 07, 2011 7:36 am

Hallo!

Nur zur weiteren Erklärung: mit 100er und 10er Berecich meine ich NICHT den Exponenten.

Federsteifigkeiten könne je nach Anwendungsfall über mehrere Zehnerpotenzen gehen, sind immer positiv und seeehr selten kleiner als 1, wobei alles über der 10e6 (in unserem Einheitensystem) als starr anzunehmen ist, d.h. zweistellige Potenzen gibt es i.d.R. nicht.. Da ich in dem 8-spaltigen Format "eingesperrt" bin möchte ich naürlich soviel Genauigkeit rausholen wie möglich, da reicht als Exponent eine Stelle.

Gemeinerweise habe ich feststellen müssen, daß %8G sich nicht immer an die 8 Zeichen Vorgabe hält :-(
Je nach Größe des Wertes ist die Ausgabe auch mal länger.

Ciao

Bruno
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Xin » Mi Dez 07, 2011 11:51 am

Bruno hat geschrieben:Hallo!

Nur zur weiteren Erklärung: mit 100er und 10er Berecich meine ich NICHT den Exponenten.

Federsteifigkeiten könne je nach Anwendungsfall über mehrere Zehnerpotenzen gehen, sind immer positiv und seeehr selten kleiner als 1, wobei alles über der 10e6 (in unserem Einheitensystem) als starr anzunehmen ist, d.h. zweistellige Potenzen gibt es i.d.R. nicht.. Da ich in dem 8-spaltigen Format "eingesperrt" bin möchte ich naürlich soviel Genauigkeit rausholen wie möglich, da reicht als Exponent eine Stelle.
Wenn Du Genauigkeit in 8 ASCII-Zeichen festhalten musst, dann rate ich Dir ein eigenes Format, nicht menschenlesbares Format zu verwenden, zum Beispiel an BASE64 angelehnt. Pro 4 Byte bekommst Du 24 Bit gespeichert. Du hast also 48 Bit.
10^6 sind 1'000'000, das sind 10 Bit.
Vorzeichen brauchst Du nicht, 0 Bit.
Bleiben 38 Bit über, womit Du fast die Genauigkeit einer Double-Mantisse (53 Bit) nicht erreichst, aber deutlich mehr als eine Float (23 Bit-Mantisse).
Die 8 Byte werden dann mit einer wilden Kombination aus Buchstaben und Zahlen gefüllt.
Wenn Du binär speichern kannst, kannst die Double auch unverändert speichern.

Wenn es wirklich auf Genauigkeit ankommt, dann rate ich von eine Dezimaldarstellung deutlich ab.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Bruno » Mi Dez 07, 2011 12:06 pm

Hallo!

Gute Idee, aber der Parser, der dann den von mir generierten Output liest, verlangt ASCII.

Es MUSS also irgendwas in der Form 1.2345E6 sein, d.h. mit zweistelligem Exponenten und Vorzeichen verliere ich zwei Stellen Genauigkeit.

1.2345E6 vs. 1.23E+06 ==> der Parser liest beides aber das erste Format ist "genauer"

Da ich quasi nur von einem Format (daß i.d.R. eine höhere Genauigkeit liefert) in ein anderes umformatiere wäre es für den Anwender auch nicht akzeptabel hier einen Genaugkeitsverlust reinzuprogrammieren. Mit der aktuellen (aber wesentlich aufwändigeren) Prozeßkette bleibt nämlich die Genauigkeit erhalten.

Wegen dieser Rahmenbedingungen (ASCII, 8-spaltiges Format) muß ich das irgendwie in C selbst lösen.

Da muß ich mich wohl mal tiefer mit sprintf befassen, evt. hilft mir das weiter...
"21" ist nur die halbe Wahrheit...

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Xin » Mi Dez 07, 2011 1:12 pm

Bruno hat geschrieben:Da muß ich mich wohl mal tiefer mit sprintf befassen, evt. hilft mir das weiter...
Gut, das ist natürlich unschön...

Damit Du das sicherstellst, würde ich vermutlich versuchen eine eigene Routine zu schreiben.
Um den Exponenten zu erhalten, teilst Du solange durch 10, bis das Ergebnis >=1.0 und <10.0 ist. Du zählst, wie oft Du teilst, und hast den Exponenten als Integer. Genauer wird es, wenn Du statt einer schleife mit /10 eine Tabelle nimmst, die je nach Index 10, 100, 1000 usw. ausgibt. Da Du aber sowieso massiv Daten vernichtest, kommt es darauf auch nicht an.

Du hast nun eine Zahl 1.2345678 (Exponent 1) und einen Exponenten als Integerzahl. Die Zahl kannst Du mit sprintf() dann wieder zusammensetzen.

Code: Alles auswählen

int exponent = 0;

while( zahl >= 10.0 )
{
  exponent++;
  zahl /= 10;
}
char buffer[9];  // 8 + Nullbyte

if( exponent < 10 )
{
  sprintf(buffer, "%.4eE%d", zahl, exponent )
}
else 
{
  printf( "Exponent zu groß darf nicht vorkommen (z.B. auf 9.9999E9 setzen)\n";
  strcpy( buffer, "9.9999E9" );
}

printf( "Ausgabe: %s\n", buffer );
Der Code ist jetzt nur mal dahergedichtet... ob er funktioniert?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Bruno
Beiträge: 41
Registriert: Do Jul 14, 2011 7:04 am

Re: Fomatierungszeichen %G für printf => Exponent beeinfluss

Beitrag von Bruno » Mo Dez 12, 2011 1:26 pm

Hallo!

Bin jetzt erst wieder zu diesem Programm gekommen

So klappts!

Danke nochmal!

Code: Alles auswählen

#include <stdio.h>
#include <string.h>
int main(){

float Zahl=99999;

int Exponent=0;

char buffer[9];  // 8 + Nullbyte

while( Zahl >= 10.0 )
{
  Exponent++;
  Zahl /= 10.;
}

if( Exponent < 10 )
{
  sprintf(buffer, "%.4fE%d", Zahl, Exponent );
}
else 
{
  printf( "Exponent zu gross darf nicht vorkommen (z.B. auf 9.9999E9 setzen)\n");
  strcpy( buffer, "9.9999E9" );
}

printf( "Ausgabe: %s\n", buffer );

}
"21" ist nur die halbe Wahrheit...

Antworten