Entwickler-Ecke
Basistechnologien - Formatierte Ausgabe eines Messwertes
Ivy - Mo 19.07.10 09:19
Titel: Formatierte Ausgabe eines Messwertes
Hallo zusammen,
ich habe die Aufgabe ein Programm zu erstellen, das einen eingeben Wert formatiert wieder ausgibt. Die Funktion soll dabei automatisch den Prefix der Einheit anpassen!
Also die Präfixe wären in diesem FAll: f, p, n, µ, m, k, M, G, T"
(siehe:
http://de.wikipedia.org/wiki/Vors%C3%A4tze_f%C3%BCr_Ma%C3%9Feinheiten)
Parameter:
- Messwert als double
- Anzahl signifikanter Stellen (das ist nicht zwangsläufig die Anzahl der Nachkommastellen!)
- Einheit
- Ein optionales Flag, welches Kennzeichnet, ob die Prefixe "f, p, n, µ, m" verwendet werden dürfen.
(manchmal macht es keinen Sinn z.Bsp. aus 0.5 Hz 500 mHz zu machen)
Eine Beispiel ausgabe könnte so aussehen:
Messwert 2.51236 V
signifikanter Stellen 3
Ausgabe 2.51 V
Messwert 0.251236 V
signifikanter Stellen 3
Ausgabe 251 mV
Messwert 2512.36 V
signifikanter Stellen 3
Ausgabe 2510 kV
Messwert 2512.36 V
signifikanter Stellen 5
Ausgabe 2512.4 kV
Messwert 2512360 V
signifikanter Stellen 3
Ausgabe 2.51 MV
Ich hab keine Ahnung wie ich das machen soll, vielleicht kann mir jemand einen guten Denkanstoß geben =)
lg ivy
Moderiert von
Christian S.: Topic aus WinForms verschoben am Mo 19.07.2010 um 09:28
IsNull - Mo 19.07.10 10:26
Hallo,
Als Grundansatz würde ich etwas in der Richtung vorschlagen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| public enum VoltEntity{ V, mV, KV }
public class Volt { private double mValue; Dictionary<VoltEntity, float> DependencyTable; public Volt() { SetUpDependencyTable(); }
public string GetValueInOptimal(bool AddPrefix = true) { }
private VoltEntity FindBestVoltEntity(){ }
public double GetVoltAs(VoltEntity entity) {
if (DependencyTable.ContainsKey(entity)) { return mValue * DependencyTable[entity]; } else { return 0; } }
private void SetUpDependencyTable(){
DependencyTable = new Dictionary<VoltEntity, float>(); DependencyTable.Add(VoltEntity.KV, 1000f); DependencyTable.Add(VoltEntity.mV, 0.001f); }
} |
Der Ansatz ist, dass du in der Klasse Volt intern deine Voltanzahl immer in Volt speicherst. D.h. beim Instanzieren der Volt Klasse müsstest du etwaige Prefixe/Suffixe schon auswerten und dann auch anhand der DependencyTable in Volt umrechnen.
Dann kannst du zumindest mal die Umrechnungen mit der DependencyTable einfach und übersichtlich lösen. Die Problematik mit der Signifikanten Stellen wird vom Code noch nicht beachtet, aber das sollte dann noch eine kleinigkeit sein.
Schau dir den Code mal an und versuche ihn weiterzuentwickeln.
Ivy - Mo 19.07.10 11:05
Hey,
super danke, das hat mich schonmal ein ganzes stück weiter gebracht. Habe deinen Code jetz erweitert, nur wie ich das mit den signifikanten stellen machen soll weiß ich noch nicht^^
und was muss ich in der Methode GetValueInOptimal und FindBestVoltEntity genau machen?
norman2306 - Mo 19.07.10 11:27
Ich würde es in eine Funktion packen.
Du hast eine Funktion mit vier eingaben: die Realzahl zum Konvertieren und die Ganzzahl signifikanter Stellen. Dann noch die Einheit und ein bool, ob die Präfixe verwendet werden soll. Und diese Funktion gibt dir einen string zurück.
C#-Quelltext
1: 2: 3:
| private string ConvertToPhysikal(double value, int significance, string unit,bool usePrefix) { } |
so, in der Funktion zählst du die Anzahl der Stellen, die deine Zahl hat. Da es mit dem zählen für den Rechner etwas kompliziert ist, bedienst du dich eines kleinen Tricks:
du nimmst den log10 der Zahl, denn
log 0,000001 = -6 := µ
log 0,001 = -3 := m
log 1000 = 3 := k
Die anderen Zahlen liegen immer dazwischen.
usw.
Das Ganze kannst du dann in eine Switch oder if schleife bauen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| string prefix = ""; double devisor = 1; switch((int)(value != 0 ? Math.Log10(value)/3 : 0)) { case: -5 prefix = "f"; devisor = 10e-15; case: -4 prefix = "p"; devisor = 10e-12; . . . case: 3 prefix = "G"; devisor = 10e9; . . . default: prefix = ""; devisor = 1; } |
obwohl ich glaube, das die Angabe der Signifikanz so wie du es machst wenig sinnvoll ist (normalerweise gibt die Signifikanz die Anzahl der Kommastellen) kann man das wieder mit dem logarithmus lösen. Mal qualitativ angegeben:
C#-Quelltext
1: 2:
| int rad = 10^((-Floor(log10(value))+significance - 1); double rvalue = Math.Round(value * rad,0)/rad; |
rvalue.ToString() liefert dir jetzt die korrekte Ausgabe (du könntest es auch über Format machen, aber ich denke, dass wäre komplizierter.
Also jetzt noch zusammenbauen mit einem StringBuilder, den Devisor nicht vergessen und das war´s dann auch schon.
Ivy - Mo 19.07.10 15:27
aha, ja klingt logisch. Aber, wie was mit dem String Builder machen? versteh ich nicht so ganz^^
und warum setzte ich den devisor = 1? braucht man doch nicht oder?
norman2306 - Mo 19.07.10 16:02
Eigentlich solltest du dir ja auch selber ein paar Gedanken machen und wenn du nicht weiter kommst, fragen. So steht´s in den Forumsregeln.
Den Devisor brauchst du, um ihn mit deinem Value zu multiplizieren... der gibt die Kommaverschiebung an, wenn du einen Präfix davorsetzt. So zu sagen der Dezimalshift. Wenn du als Präfix "k" hast, musst du dein value ja durch tausend rechnen, weil k = 1000.
also 1000 = 1 kHz, also devisor = 1000 = 10^3.
Ivy - Mo 19.07.10 16:10
wer sagt dass ich mir keine gedanken gemacht habe? Vielleicht habe ich mich einfach nachdem ich mir gedanken gemacht habe und google befragt habe dazu entschlossen, hier noch einmal nachzufragen. weil wie du siehst ist zwischen deiner antwort un meinem post jede menge zeit vergangen...aber gut^^
norman2306 - Mo 19.07.10 16:19
poste deinen bisherigen Code. Das ist immer der schlagfertigste Beweis:) Dann weiß ich a) dass du was gemacht hast und b) wo genau dein Problem liegt. Code sagt mehr, als tausend Worte.
Ivy - Di 20.07.10 08:07
okay, also bisher hab ich deine funktion für die signifikanten stellen so:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
| private string ConvertToPhysikal(double value, int significance, string unit, bool usePrefix) { string prefix = ""; double devisor = 1; switch((int)(value != 0 ? Math.Log10(value)/3 : 0)) { case -5: prefix = "f"; devisor = 10e-15; break; case -4: prefix = "p"; devisor = 10e-12; break; case -3: prefix = "n"; devisor = 10e-9; break; case -2: prefix = "µ"; devisor = 10e-6; break; case -1: prefix = "m"; devisor = 10e-3; break; case 1: prefix = "k"; devisor = 10e-3; case 3: prefix = "G"; devisor = 10e-9; break; case 4: prefix = "T"; devisor = 10e-12; break; default: prefix = ""; devisor = 1; break; } StringBuilder MyStringBuilder = new StringBuilder(); MyStringBuilder.AppendFormat(prefix, devisor); return string.Format(prefix + "{0}"); |
Christoph1972 - Di 20.07.10 09:14
Moin,
ich dachte hier werden keine Hausaufgaben erledigt :lol:
Ivy - Di 20.07.10 09:18
Christoph1972 hat folgendes geschrieben : |
Moin,
ich dachte hier werden keine Hausaufgaben erledigt :lol: |
sind kine hausaufgaben, ist ein projekt was ich in der arbeit erledigen muss :-/ wenn mand as nicht darf, wozu ist das forum dann?
norman2306 - Di 20.07.10 09:19
Naja... du weißt nicht so richtig, was du da machst^^
das return macht keinen Sinn. Das hatte ich in meinem ersten Post nur versehentlich drin.
Also gehen wir mal durch, was das der Code jetzt macht. Legen wir uns mal ein paar Werte vor:
C#-Quelltext
1: 2: 3: 4:
| value = 123456.78 significance = 4 unit = "m" usePrefix = true |
Nach kurzem überlegen sollte da also rauskommen: 123.5 km
das erste was jetzt gemacht wird, ist die switch-Anweisung... also es wird Math.Log10(value)/3 berechnet
C#-Quelltext
1:
| Math.Log10(123456.78)/3 = 1.6971 |
durch die (int)-Umwandlung wird das ganze automatisch abgerundet, also ist das Ergebnis 1. Er geht jetzt also zum Ergebnis 1 (case 1). Bei Case 1 wird das prefix auf "k" (Kilo) und der devisor auf 10e-3 = 10^-3 = 0.001... mmh, sieht mir schonmal nach einem Fehler aus... sollte das nicht 1000, also 10e3 sein? k= 1000? Naja, das findest du schon raus. Also, gehen wir mal von einem devisor=1000 aus.
Das break gibt an, dass der Bereich der switch-Anweisung verlassen werden soll. Also, wir haben jetzt:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| value = 123456.78 significance = 4 unit = "m" usePrefix = true prefix = "k" devisor = 1000 |
jetzt sollten wir uns ja eigentlich um die signifikanten Stellen kümmern... dafür hatte ich dir ja schonmal Code gesponsert...
C#-Quelltext
1: 2:
| int rad = 10^((-Math.Floor(Math.Log10(value))+significance - 1); double rvalue = Math.Round(value * rad,0)/rad; |
Das ergibt in unserem Beispiel:
C#-Quelltext
1: 2:
| int rad = 10^((-Math.Floor(Math.Log10(123456.78))+ 4 - 1) = 10e-2 = 0.01 double rvalue = Math.Round(value * 0.01,0)/0.01 = 123500 |
Fassen wir zusammen, was wir jetzt haben:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| value = 123456.78 significance = 4 usePrefix = true
rvalue = 123500.0; devisor = 1000 prefix = "k" unit = "m" |
Das sieht ja schon recht brauchbar aus... jetzt fragen wir uns mal, was wir haben wollten:
123.5 km. Die Frage ist nun, wie wir das aus den Sachen da oben bekommen. Ich meine, wie machen wir z.B. mit Hilfe des devisors = 1000 aus dem rvalue = 123500 unser nominales Ergebnis von 123.5????
Und wie setzen wir mit Hilfe des StringBuilders das dann zu einem brauchbaren ("123.5 km") Text zusammen
Und zu guter letzt gilt es ja dann auch noch usePrefix auszuwerten... Aber ich denke, dass sind lösbare Aufgaben.
norman2306 - Di 20.07.10 09:27
| Zitat: |
| wenn mand as nicht darf, wozu ist das forum dann? |
In diesem Forum wird geholfen, wenn jemand an einem Punkt nicht weiter kommt. Normalerweise wir nur auf explizite Fragen geantwortet. Besonders wenn es sich um recht einfache Dinge handelt. Fertiger Code wird nur in Ausnahmefällen geliefert (bei meist komplexen Sachen oder Optimierungsaufgaben)...
Ivy - Di 20.07.10 10:01
ja sorry, tut mir ja leid dass ich ein wenig zu doof bin -.-
zu diesem code schnipsel:
C#-Quelltext
1: 2:
| int rad = 10^((-Math.Floor(Math.Log10(value))+significance - 1); double rvalue = Math.Round(value * rad,0)/rad; |
ich hatte ihn wieder herausgenommen da ein fehler kam; "Der Operator "^" kann nicht auf Operanden vom Typ "int" und "double" angewendet werden"
ansonsten ist es mir jetz schon klarer geworden, dank deiner schritt für schritt (für doofe) erklärung
beim Case1 habe ich jetz statt -3, +3 (10e3 = 10^3 = 1000)
| Zitat: |
| Ich meine, wie machen wir z.B. mit Hilfe des devisors = 1000 aus dem rvalue = 123500 unser nominales Ergebnis von 123.5???? |
123500/1000=123,5 oder?
norman2306 - Di 20.07.10 10:20
jop, "^" ist auch nicht korrekt, dass ist aus EXCEL. Mein Code enthält schon aus Prinzip Fehler. Du musst
C#-Quelltext
1:
| Math.Pow(10, -Math.Floor(Math.Log10(value)+significance - 1) |
stattdessen schreiben.
Du musst das auch bei allen anderen "Case > 0" ändern.
Ivy - Di 20.07.10 11:01
okay, bin jetz mal so weit:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:
| private string ConvertToPhysikal(double value, int significance, string unit, bool usePrefix) { string prefix = ""; double devisor = 1; switch ((int)(value != 0 ? Math.Log10(value) / 3 : 0)) { case 1: prefix = "k"; devisor = 10e3; break; case 2: prefix = "M"; devisor = 10e6; break; case 3: prefix = "G"; devisor = 10e9; break; case 4: prefix = "T"; devisor = 10e12; break; case -5: prefix = "f"; devisor = 10e-15; break; case -4: prefix = "p"; devisor = 10e-12; break; case -3: prefix = "n"; devisor = 10e-9; break; case -2: prefix = "µ"; devisor = 10e-6; break; case -1: prefix = "m"; devisor = 10e-3; break; default: prefix = ""; devisor = 1; break; } double rad = Math.Pow(10, -Math.Floor(Math.Log10(value) + significance - 1)); double rvalue = Math.Round(value * rad, 0) / rad;
System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(rvalue/devisor); sb.Append(prefix); sb.Append("Volt"); return sb.ToString(); |
Was genau muss ich noch mit dem useprefix machen?
norman2306 - Di 20.07.10 14:47
Das usePrefix hast du in deiner Aufgabenstellung bereits gesagt....
du machst ja:
C#-Quelltext
1: 2: 3: 4:
| sb.Append(rvalue/devisor); sb.Append(prefix); sb.Append("Volt"); return sb.ToString(); |
aber was ist zum Beispiel bei Hz?
also machst du ein Konstrukt wie
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| if(!usePrefix && devisor < 1) { } else { } |
Außerdem würde ich den Text "Volt" noch durch <unit> ersetzen, die du ja der Funktion übergibst. Mal davon abgesehen ist es unüblich, kVolt anzugeben. Das entspricht nicht den SI-Richtlinien. Entweder kV oder Kilovolt.
Ivy - Di 27.07.10 08:52
Hey,
ich habe jetzt nochmal nachgerechnet, wie kommst du eigentlich drauf
Math.Log10(123456.78)/3 = 1.6971 ergbit?
wenn ich 123456.78/3 rechne bekomme ich 41152.26 heraus?!
und bei diesem:
C#-Quelltext
1:
| int rad = 10^((-Math.Floor(Math.Log10(123456.78))+ 4 - 1) = 10e-2 = 0.01 |
wie kommst du da auf 10^-2?
danielf - Di 27.07.10 08:57
Das nennt sich Mathematik.
Er rechnet nicht 123456,78 / 3 sondern den Logarithmus von 123456,78 und das Resultat durch 3..
10^-2 ist eine andere Schreibweise für 0.1 ...
Findest du bestimmt auch alles in deine Mathebücher oder bei google.
Ivy - Di 27.07.10 09:08
ahja...noch nie von logarthismus gehört^^
ich hab noch ein problem, rvalue setzt mein programm immer auf 0, also rechnet nicht das
C#-Quelltext
1:
| double rvalue = Math.Round(value * ergebnis, 0) / ergebnis; |
hat jemand ne ahnung warum? bin noch am verzweifeln -.-
edit: habs gelöst durch die 0 hatte mein rvalaue keine dezimalstellen
norman2306 - Di 27.07.10 09:22
Da müsste man den gesammten Code sehen. Die 0 kommt raus, weil entweder value 0 ist oder value * ergebnis zu klein ist, was aber bei dem Code den ich gepostet habe nicht passieren sollte. Leider weiß ich nicht, was du davor machst.
Ivy - Di 27.07.10 10:24
ja das mit der 0 hatte ich jetzt auch schon herausgefunden
davor mach ich nur:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:
| unit = "V"; string prefix = ""; double devisor = 1; switch ((int)(value != 0 ? Math.Log10(value) / 3 : 0)) { case -5: prefix = "f"; devisor = 10e-14; break; case -4: prefix = "p"; devisor = 10e-11; break; case -3: prefix = "n"; devisor = 10e-8; break; case -2: prefix = "µ"; devisor = 10e-5; break; case -1: prefix = "m"; devisor = 10e-2; break; case 1: prefix = "k"; devisor = 10e2; break; case 2: prefix = "M"; devisor = 10e5; break; case 3: prefix = "G"; devisor = 10e8; break; case 4: prefix = "T"; devisor = 10e11; break; default: prefix = ""; devisor = 1; break; } double ergebnis = Math.Pow(10, -Math.Floor(Math.Log10(value) + significance - 1)); |
es funktioniert jetzt auch fast, nur beachtet er die signifikanten srtellen eben noch net so wirklich also z.b:
0,000251236V
signifikanz: 3
ausgabe: 0,00025126mV
2512,36V
sig.: 5
ausgabe: 2,51kv
sehr komisch...
norman2306 - Di 27.07.10 14:20
ich würde sagen, dann hast du irgendetwas nicht korrekt umgesetzt. Ich habe den Code den ich gepostet habe getestet und er funktioniert einwandfrei^^ Vielleicht sendest du mal deinen kompletten Code, dann kann ich dir auch weiterhelfen. Das gepostete oben ist unvollständig.
Ivy - Do 29.07.10 13:38
also hier noch einmal der ganze quelltext. die ref schlüsselwörter sind zum übergeben der parameter gedacht ;)
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68:
| public string ConvertTo(ref double value, ref int significance, ref string unit, ref bool usePrefix) { unit = "V"; string prefix = ""; double devisor = 1; switch ((int)(value != 0 ? Math.Log10(value) / 3 : 0)) { case -5: prefix = "f"; devisor = 10e-14; break; case -4: prefix = "p"; devisor = 10e-11; break; case -3: prefix = "n"; devisor = 10e-8; break; case -2: prefix = "µ"; devisor = 10e-5; break; case -1: prefix = "m"; devisor = 10e-2; break; case 1: prefix = "k"; devisor = 10e2; break; case 2: prefix = "M"; devisor = 10e5; break; case 3: prefix = "G"; devisor = 10e8; break; case 4: prefix = "T"; devisor = 10e11; break; default: prefix = ""; devisor = 1; break; } double ergebnis = Math.Pow(10, -Math.Floor(Math.Log10(value) + significance - 1)); double rvalue = Math.Round(value * ergebnis, 6) / ergebnis; if (!usePrefix && devisor < 1) { } else { } System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(rvalue / devisor); sb.Append(prefix); sb.Append(unit); return sb.ToString(); } |
mit unsrem beispiel wert 123456,78 sig. 4 funktioniert es übrigens. kommt 123,5kV raus
norman2306 - Do 29.07.10 18:36
Das sind aber noch einige Fehler drin...
Ivy - Mo 02.08.10 07:47
norman2306 hat folgendes geschrieben : |
| Das sind aber noch einige Fehler drin... |
und die wären??
mit dem useprefix wewiß ich nicht genau wie und was ich damit anstellen soll und wo eine floor funktion fehlen soll weiß ich auch noch nicht?!
CSMN - Mo 02.08.10 20:10
was für ein genialer thread - den drucke ich mir aus und rahm in ein... ^^
Ivy - Mi 04.08.10 09:36
sorry das nicht jeder, als programmierender super nerd auf die welt kommt -.-
so viel zu "C# - Deine freundliche C# und .NET Community"
danielf - Mi 04.08.10 09:43
@offtopic
Also eigentlich sollte man das euch untereinander austragen lassen, aber ich habe frei und was ist da besser also Morgens zum Kaffee sich an einer Diskussion zu beteiligen (Nerd :o).
CSMN seine Kommentare überlese ich hier im Forum, weil die noch nie besonders geistreich waren.
@Ivy dass du von einem Kommentar die ganze Hilfe die du hier bekommst ins lächerliche ziehst spricht nicht für dich.
Ich wünsche beiden ein bisschen mehr Rückgrad, weil es gibt hier viele die Spaß am Austauch von Informationen und Hilfestellungen haben.
So kommt runter und noch einen schönen Tag,
Gruß
CSMN - Mi 04.08.10 19:22
@Ivy das war mehr spaß als ernst :shock: sorry!
@danielf wenn du meine kommentare wegen mangelnder geistreichtigkeit überlesen tust, wie kommt es dann das du drauf reagierst :wink:
Ivy - Do 05.08.10 08:38
CSMN hat folgendes geschrieben : |
@Ivy das war mehr spaß als ernst :shock: sorry!
@danielf wenn du meine kommentare wegen mangelnder geistreichtigkeit überlesen tust, wie kommt es dann das du drauf reagierst :wink: |
er hat wohl eher auf meinen Beitrag reagiert :/
Naja mir wärs recht, wenn wir jetzt wieder zum thema zurück kommen würde...
CSMN - Do 05.08.10 10:00
soooo Ivy,
das erste was mir aufgefallen ist, dass du unit an die funktion übergibst und dann gleich wieder überschreibst - das macht nicht wirklich viel sinn (sowas nennt man auch dd-anomalie). das hauptproblem wird aber die switch-anweisung sein bzw. die bedingung die du da reingeschrieben hast. wenn du z.b. 0.0012345 als value übergibst dann sollten ja 1,2345 mV rauskommen. durch die bedingung (int)(value != 0 ? Math.Log10(value) / 3 : 0) wird aber switch(0) ausgeführt und du springst in den default bereich. ich würde dir raten die bedingung auszulagern, d.h. vorher zu berechnen int bedingung =.... und im anschluß dann switch(bedingung){...} zu verwenden. weiter habe ich erstmal nicht geschaut... achso, warum verwendest du das schlüsselwort ref? dass muss dort nicht sein. parameter kannst du einfach mit dem typ übergeben sofern du nicht die originalen werte innerhalb der funktion weiterbearbeiten möchtest. zum beispiel public int GGT(int T1, int T2)...
die grundlagen solltest du mal nen bisschen mit galileo openbooks, oder so nacharbeiten...
Ivy - Do 05.08.10 11:40
ja was bringt es wenn ich die bedinung auslagere, es wird ja trotzdem noch das gleiche berechnet. ergibt für mich keinen sinn^^
C#-Quelltext
1: 2: 3:
| int bedingung = (int)(value != 0 ? Math.Log10(value) / 3 : 0);
switch (bedingung) |
CSMN - Do 05.08.10 14:06
du hast es falsch verstanden! natürlich musst du die bedingung überarbeiten!
ich dachte nur, dass es für dich einfacher wäre dir die bedingung im detail
anzuschauen - was von aussen einfacher ist... nun, roger?
Ivy - Do 05.08.10 14:09
ahja ^^ nur weiß ich nicht was an der bedingung falsch ist und wa sich da ändern soll
CSMN - Do 05.08.10 14:10
was soll die bedingung denn machen?
Ivy - Do 05.08.10 14:12
ja ausrechnen in welchen case mein programm springen soll. das mit dem logarthismus versteh ich nich, wie das gerechnet wird.
CSMN - Do 05.08.10 14:22
hmmm, wenn du das nicht verstehst, warum schreibst du dir dann nicht ein kleines skript in welchen du dir alle fälle einmal anschaust wie sie aussehen wenn du die operation [Math.Log10(value) / 3] auf den value anwendest? mit fälle meine ich deine unterschiedlichen einheiten von µ bis M. oder du nimmst dein derzeitiges programm und setzt dir an der stelle nen breakpoint, gehst in den debugmodus und ziehst dir die bedingung in den überwachungsbereich - so kannst du auch schauen was passiert und warum die gewünschten cases nicht angesprungen sondern der default angewählt wird. dadurch sollte dir das prinzip eigentlich klar werden.
wenn du jedoch die mathematik dahinter verstehen möchtest, solltest du dir ein mathebuch anschauen.
CSMN - Do 05.08.10 14:26
norman2306 hat folgendes geschrieben : |
du nimmst den log10 der Zahl, denn
log 0,000001 = -6 := µ
log 0,001 = -3 := m
log 1000 = 3 := k
|
norman2306 hatte mit den obigen zeilen eigentlich auch schon sehr deutlich das prinzip dargestellt.
Ivy - Do 05.08.10 14:31
debugger hab ich ja schon durch laufen lassen, aber wie die rechnung funktioniert wird mir da auch nicht angezeit, geschweigeden die logik die dahinter steckt.
ja das von norman hab ich ja dann auch so umgesetzt, hab ich ja eig alles so^^
CSMN - Do 05.08.10 15:26
wenn du den wert 0,01154 [V] als value nimmst, was ist dann das sollergebnis und das istergebnis? in welchen case springt das program? und welcher wert ergibt sich durch Math.Log10(value) / 3?
Ivy - Do 05.08.10 15:28
bei 0,01154 ist es 10^-1 , -1 / 3 = -0,3333 ~ -1 springt in case -1
richtig?
CSMN - Do 05.08.10 15:30
und was sagt der debugger dazu? bestätigt er dir das?
Ivy - Do 05.08.10 15:31
:D ja tut er^^
aber das ergebnis stimmt trotzdem nicht...
CSMN - Do 05.08.10 15:36
Ivy hat folgendes geschrieben : |
:D ja tut er^^
aber das ergebnis stimmt trotzdem nicht... |
also bei den code den du gepostet hast macht er das jedenfalls nicht!
Ivy - Do 05.08.10 15:39
ja ich habs bei mir nochmal bissl umgeändert, immer wenn der value jetzt kleiner als 0 is rechnet er folgendes:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| if (value <= 1) { bedingung = (int)(value != 0 ? Math.Log10(value):0); } else { bedingung = (int)(value != 0 ? Math.Log10(value) / 3 : 0); } |
damit funktionierts
CSMN - Do 05.08.10 15:45
und in welchen fällen stimmt das ergebnis nicht?
CSMN - Do 05.08.10 15:48
Ivy hat folgendes geschrieben : |
ja ich habs bei mir nochmal bissl umgeändert, immer wenn der value jetzt kleiner als 0 is rechnet er folgendes:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| if (value <= 1) { bedingung = (int)(value != 0 ? Math.Log10(value):0); } else { bedingung = (int)(value != 0 ? Math.Log10(value) / 3 : 0); } |
damit funktionierts |
in den quelltext steht ab nicht kleiner als null sondern kleiner gleich eins...
Ivy - Do 05.08.10 15:48
ja wenn ich jetz 0,0251236 eingeb kommt raus 2,51mV, gut die einheit stimmt jetzt ja schonmal aber als ergebnis sollte eigetnlich 25,124 rauskommen
ja sorry habs grad in 0 geändert, war noch nen versuch vorher^^
CSMN - Do 05.08.10 15:56
Ivy hat folgendes geschrieben : |
ja wenn ich jetz 0,0251236 eingeb kommt raus 2,51mV, gut die einheit stimmt jetzt ja schonmal aber als ergebnis sollte eigetnlich 25,124 rauskommen
ja sorry habs grad in 0 geändert, war noch nen versuch vorher^^ |
na dann hauste wohl eine stelle zuviel weg ^^
CSMN - Do 05.08.10 16:13
^^... du wirst es schon finden...
wenn nicht kannst ja später nochmal ne komplette version deines codes posten...
Ivy - Fr 06.08.10 09:34
hmm.. also ich hab keine ahnung warums nicht geht, hier nochmal der komplette code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78:
| public string ConvertTo(double value, int significance, string unit, bool usePrefix) { unit = "V"; string prefix = ""; double devisor = 1; int bedingung = 0; if (value <= 1) { bedingung = (int)(value != 0 ? Math.Log10(value):0); } else { bedingung = (int)(value != 0 ? Math.Log10(value) / 3 : 0); }
switch (bedingung) { case -5: prefix = "f"; devisor = 10e-14; break; case -4: prefix = "p"; devisor = 10e-11; break; case -3: prefix = "n"; devisor = 10e-8; break; case -2: prefix = "µ"; devisor = 10e-5; break; case -1: prefix = "m"; devisor = 10e-3; break; case 1: prefix = "k"; devisor = 10e2; break; case 2: prefix = "M"; devisor = 10e5; break; case 3: prefix = "G"; devisor = 10e8; break; case 4: prefix = "T"; devisor = 10e11; break; default: prefix = ""; devisor = 1; break; } if (!usePrefix && devisor < 1) { } else { } double ergebnis = Math.Pow(10, -Math.Floor(Math.Log10(value) + significance -1)); double rvalue = Math.Round(value * ergebnis,significance+1) / ergebnis; System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append(rvalue / devisor); sb.Append(prefix); sb.Append(unit); return sb.ToString(); } |
Ivy - Mo 30.08.10 11:10
keiner ne idee warum? :( bin solangsam echt am verzweifeln
ich habe folgende ausgaben:
Wert: 2,51236
Sig.: 3
Erg: 2,51V RICHTIG
Wert: 2,51236
Sig.: 5
Erg: 2,51V FALSCH eig 2,5124V
Wert: 0,251236
Sig.: 3
Erg: 0,251V FALSCH eig 0,251mV
Wert: 0,0251236
Sig.: 5
Erg: 2,51mV FALSCH eig 25,124mV
Wert: 251236
SIg.: 3
Erg.: 2,51MV RICHTIG
Kha - Mo 30.08.10 13:32
Das Runden kann so nicht funktionieren, versuch es lieber so:
C#-Quelltext
1: 2:
| double lastSignificantDigit = Math.Pow(10, (int)(Math.Log10(value) - significance)); double rvalue = Math.Round(value / lastSignificantDigit) * lastSignificantDigit; |
Dann wären da noch ein paar Punkte, die dir im Debugger wirklich hätten auffallen müssen, wenn du dich mit der Mathematik dahinter auseinandersetzen würdest:
- Das Teilen des Logarithmus durch 3 muss natürlich in beiden Fällen drin bleiben (es ist also überhaupt keine Fallunterscheidung nötig), schließlich sind es in beide Richtungen 10³-Schritte.
- Das Ergebnis dieser Division muss erst einmal mit Math.Floor abgerundet werden
- 10^-3 != 10e-3 :!:
PS: Ein StringBuilder ist hier unnötig, nimm
string.Format oder einfach "+". Und es heißt D
ivisor ;) .
Ivy - Mo 30.08.10 13:41
Kha hat folgendes geschrieben : |
- Das Teilen des Logarithmus durch 3 muss natürlich in beiden Fällen drin bleiben (es ist also überhaupt keine Fallunterscheidung nötig), schließlich sind es in beide Richtungen 10³-Schritte.
- Das Ergebnis dieser Division muss erst einmal mit Math.Floor abgerundet werden
- 10^-3 != 10e-3 :!:
|
Das mit dem durch 3 hatte mir mein Chef so gesagt^^ naja habs wieder rausgenommen
Welche Division meinst du? diese?!
C#-Quelltext
1:
| ^(int)(value != 0 ? Math.Log10(value) / 3 : 0) |
10^-3 != 10e-3??? 10e-3 ist doch das selbe wie 10^-3 :?:
Yogu - Mo 30.08.10 13:44
Ivy hat folgendes geschrieben : |
| 10^-3 != 10e-3??? 10e-3 ist doch das selbe wie 10^-3 :?: |
Nein, 10e-3 = 10x10^-3 != 10^-3.
Ivy - Mo 30.08.10 13:51
ahja... habs jetz mal überall geändert, aber jetzt kommen noch komischere zahlen raus :/
Kha - Mo 30.08.10 14:14
Ivy hat folgendes geschrieben : |
| Welche Division meinst du? diese?! |
Jupp. Aus 0,2 soll ja 200e-3 werden. lg(0,2) ist -0.69..., durch 3 und abgerundet -1, also milli.
Ivy hat folgendes geschrieben : |
| ahja... habs jetz mal überall geändert, aber jetzt kommen noch komischere zahlen raus :/ |
Aber hoffentlich nicht an den Stellen, die schon korrekt waren (10e2 z.B.)?
Mit meinen vier Vorschlägen habe ich für deine Beispiele jedenfalls die richtigen Zahlen herausbekommen.
Ivy - Mo 30.08.10 14:28
achso nur bei den negativen werten??
hab jetz die math.floor so eingebunden.
C#-Quelltext
1:
| value = Math.Floor(Math.Log(bedingung)); |
kommt aber als ausgabe was ganz komisches "n. def .V"
IsNull - Di 07.09.10 13:42
Der Definitions Bereich für den Log(n):
n > 0
Wenn du allso den Logarithmus von 0 oder einer negative Zahl nimmst, gibt es kein Resultat im rationalen Zahlenraum, folglich also das Ergebnis: Nicht definiert.
Ivy - Mi 08.09.10 08:42
IsNull hat folgendes geschrieben : |
Der Definitions Bereich für den Log(n):
n > 0
Wenn du allso den Logarythmus von 0 oder einer negative Zahl nimmst, gibt es kein Resultat im rationalen Zahlenraum, folglich also das Ergebnis: Nicht definiert. |
aha und das heißt jetzt??
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!