StackUnderflow abfangen?!

dannyesl

Mitglied
Hi Leute,

mein Problem:
Wird in dem Programm eine zu große Zahl eingegeben, kriege ich eine OverflowException - die ist mit try/catch abgefangen.
Wird nun aber eine Zahl eingegeben, die zu klein ist, kriege ich zwar keine Fehlermeldung, aber die Ausgabe ist ausschließlich 0!

Es handelt sich bei dem ganzen um einen IEEE-Converter mit einfacher bzw. doppelter Genauigkeit. Die Ausgaben sind also einmal in Binärform und einmal in Hexadezimal. Beide Ergebnisse sind dann 0000000000000000 bzw. 0000000000

Ich habe für die Einfache Genauigkeit den Datentyp FLOAT und für die Doppelte DOUBLE genommen. Liegt der Fehler hier?!

Danke im Voraus!!
 

dannyesl

Mitglied
Es geht um eine Eingabe wie 1,04e-60

Der minmale Wert bei der einfachen Genauigkeit ist 1,175494e-38.
Wie kriege ich es hin, dass kein kleinerer Wert eingegeben bzw. berechnet werden kann?!

Habe hier mal den gesamten Code eingefügt!
Für Verbesserungsvorschläge bin ich offen :)
Code:
    public partial class Form1 : Form 
    {
        double eingabe_double;
        float eingabe_float;
        byte[] bytes;
        string binary;
        string hex;
        string eingabe;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                eingabe = textBox1.Text;
                if (eingabe == "")
                    MessageBox.Show("Geben Sie zuerst einen numerischen Wert ein!");
                else
                {
                    read_bytes(eingabe);
                    fill_ergebnis();
                    ToHex(eingabe);
                }

            }
            else if (checkBox2.Checked)
            {
                eingabe = textBox1.Text;

                read_bytes(eingabe);
                fill_ergebnis();
                ToHex(eingabe);
            }

            textBox2.Text = hex;
            textBox3.Text = binary;

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                checkBox2.Enabled = false;
            }
            else
            {
                checkBox2.Enabled = true;
            }

            button1.Enabled = checkBox1.Checked;
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked)
            {
                checkBox1.Enabled = false;
            }
            else
            {
                checkBox1.Enabled = true;
            }

            button1.Enabled = checkBox2.Checked;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        public void read_bytes(string eingabe)
        {
            if (checkBox1.Checked)
            {
                eingabe_float = Convert.ToSingle(eingabe);
                bytes = BitConverter.GetBytes(eingabe_float);
                if (BitConverter.IsLittleEndian)
                    Array.Reverse(bytes);
            }
            else if (checkBox2.Checked)
            {
                eingabe_double = Convert.ToDouble(eingabe);
                bytes = BitConverter.GetBytes(eingabe_double);
                if (BitConverter.IsLittleEndian)
                    Array.Reverse(bytes);
            }           
        }

        public void fill_ergebnis()
        {
            binary = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                binary += Convert.ToString(bytes[i], 2).PadLeft(8, '0');
                binary += " ";                
            }
        }

        public void ToHex(string eingabe)
        {
            if (checkBox1.Checked)
            {
                byte[] byteArray = BitConverter.GetBytes(eingabe_float);
                Array.Reverse(byteArray);
                hex = BitConverter.ToString(byteArray).Replace("-", " ");
            }
            else if (checkBox2.Checked)
            {
                byte[] byteArray = BitConverter.GetBytes(eingabe_double);
                Array.Reverse(byteArray);
                hex = BitConverter.ToString(byteArray).Replace("-", " ");           
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar) && !char.IsPunctuation(e.KeyChar) && !(e.KeyChar == 'e')) 
                e.Handled = true;
        }
    }
}
 

Shakie

Erfahrenes Mitglied
Du könntest überprüfen, ob das Ergebnis der Convert.ToSingle/ToDouble-Methoden Null ist und der eingegebene Text aber mindestens eine Ziffer enthält, die nicht "0" ist (Sonderfall: 0eX mit X=beliebige Ziffer; diese Eingabe wäre natürlich gleich mit Null). Wenn ja, dann weißt du, dass der eingegebene Text eine zu kleine Zahl repräsentiert.

Sprich: du überlegst dir, welche Eingaben für die Null gültig sind. Alle anderen Eingaben, die trotzdem eine Null nach dem parsen liefern, waren zu kleine Zahlen.
 
Zuletzt bearbeitet:

dannyesl

Mitglied
Das kriege ich via try/catch abgefangen, aber danke für den hinweis, dieser Funktion!

Habe das Problem auch jetzt erst richtig verstanden:
Die Zahl 1,1e-60 ist nicht kleiner als der kleinste Single/Float wert, sondern ist zu klein um dargestellt zu werden!
Der kleinste wert (-3,7....e38) wird via try/catch abgefangen....
Der Wert 1,1e-60 ist aber zu viele Stellen hinter dem Komma (also die erste 1), als das sie in IEEE umgewandelt werden kann - zumindest so wie ich es programmiert habe.

Gebe ich bspw. 1,1e-38 ein, wandelt er den wert noch in float um!
Gehe ich aber über 1,1e-45, wird die float-Zahl einfach als 0,0 gespeichert und das Ergebnis ist logischerweise 000000000.