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 user profile iconChristian 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
    //muss natürlich mit allen Einheiten ergenzt werden
}

public class Volt
{
    private double mValue; //intern halten wir die anzahl immer als Volt
    Dictionary<VoltEntity, float> DependencyTable; //Tabelle um die Umrechnungen zu verwalten

    public Volt() {
        SetUpDependencyTable();
    }


    public string GetValueInOptimal(bool AddPrefix = true) {
        // Das ist die HauptMethode, die den Volt-Eintrag optmal zurückliefert, also in der besten grösse
    }

    private VoltEntity FindBestVoltEntity(){
        //Sucht die beste Einheit
    }
     


    /// <summary>Gibt die Volt-Value in der gewünschten Einheit zurück
    /// 
    /// </summary>
    /// <param name="VoltFormat"></param>
    /// <returns></returns>
    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);    //KiloVolt, d.h. Volt * 1000 = KV
        DependencyTable.Add(VoltEntity.mV, 0.001f);    //mV MiliVolt, d.h. Volt * 0.001 = mV
        //Hier die restilchen Umrechnungen eintragen

    }

}



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;
   .
   .
   .
   case3
     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) //Funktion Signifkikante Stellen berechnen
    {
        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

user profile iconChristoph1972 hat folgendes geschrieben Zum zitierten Posting springen:
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); //123500/1000=123,5
                sb.Append(prefix); //k
                sb.Append("Volt"); //Volt
                return sb.ToString();  //---->123,5kVolt



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); //123500/1000=123,5
                sb.Append(prefix); //k
                sb.Append("Volt"); //Volt
                return sb.ToString();  //---->123,5kVolt


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)
{
  //Ergebnis ohne Prefix
}
else
{
  //Ergebnis mit Prefix
}


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;
            //Prefix
            switch ((int)(value != 0 ? Math.Log10(value) / 3 : 0)) //123456,78/3=1,697 ~1
            {                
                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:         //Springt in 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;
            }
            //Signifikante Stellen
            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;
            //Prefix
            switch ((int)(value != 0 ? Math.Log10(value) / 3 : 0)) //123456,78/3=1,697 ~1
            {                
                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:         //Springt in 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;
            }
            //Signifikante Stellen
            double ergebnis = Math.Pow(10, -Math.Floor(Math.Log10(value) + significance - 1)); //(123456,78)+4-1= 10e-2 =0,01
            double rvalue = Math.Round(value * ergebnis, 6) / ergebnis; //(123456,78*0,01)/0,01= 123500
          
            if (!usePrefix && devisor < 1)
            {
                //Ergebnis ohne Prefix
            }
            else
            {
                //Ergebnis mit Prefix
            }
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append(rvalue / devisor); //123500/1000=123,5
            sb.Append(prefix); //k
            sb.Append(unit); //V
            return sb.ToString();  //---->123,5kV 
            
        }


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

user profile iconnorman2306 hat folgendes geschrieben Zum zitierten Posting springen:
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

user profile iconCSMN hat folgendes geschrieben Zum zitierten Posting springen:
@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

user profile iconnorman2306 hat folgendes geschrieben Zum zitierten Posting springen:

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

user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
: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

user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
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

user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
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 ^^


Ivy - Do 05.08.10 16:03

user profile iconCSMN hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
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 ^^


hm ja scheint so, aber wo und warum weiß ich noch nicht^^


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);//123456,78/3=1,697 ~1
            }

            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:    //Springt in 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)
            {
                //Ergebnis ohne Prefix
            }
            else
            {
               //return rad.ToString();
            }
           
            //Signifikante Stellen
            double  ergebnis = Math.Pow(10, -Math.Floor(Math.Log10(value) + significance -1)); //(123456,78)+4-1= 10e-2 =0,01
            double rvalue = Math.Round(value * ergebnis,significance+1) / ergebnis; //(123456,78*0,01)/0,01= 123500
                        
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append(rvalue / devisor); 
            sb.Append(prefix); //k
            sb.Append(unit); //V
            return sb.ToString();  //---->123,5kV 
            
        }


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:


PS: Ein StringBuilder ist hier unnötig, nimm string.Format oder einfach "+". Und es heißt Divisor ;) .


Ivy - Mo 30.08.10 13:41

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:


  • 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

user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
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

user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconIvy hat folgendes geschrieben Zum zitierten Posting springen:
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

user profile iconIsNull hat folgendes geschrieben Zum zitierten Posting springen:
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??