none
Probleme mit EXCEL 2007 Dateityp Single in Makro RRS feed

  • Frage

  • Ich habe den Wunsch Primzahlen in großer Zahl zu errechnen und benutze ein Makro in folgender Form:

    Const sp As Long = 10380000, anz As Long = sp * 19 + 1000000 'sp: max. Spaltenlänge, anz = max Anzahl
    Dim Prim(anz) As Single, a As Double, b As Long, x As Long, flag As Boolean, t0
    Sub Test() ' Makro am 5.11.2011 von Dietrich Möhring aufgezeichnet
      Dim h As Long, i As Long, j As Long, fn As Long
        Columns("A:B").Select
        Selection.NumberFormat = "#,##0"
        Range("A1").Select
        For i = 16777200 To 16777230 'Step 1
          Prim(i) = i
            ActiveCell.Value = i
            ActiveCell.Offset(0, 1).Range("A1").Select
            ActiveCell.Value = Prim(i)
            ActiveCell.Offset(1, -1).Range("A1").Select
        Next i
    End Sub

    Die Programmierung ist möglich aber wenn ich den Test laufen lasse, bekomme ich unerwartete Ergebnisse denn die Darstellung der Zahlen > 16777216 ist fehlerhaft, zum Einen werden nur gerade Zahlen angezeigt, zum Andern springt das Ergebnis. Ich benutze einen Prozessor AMD Athlon II X2 bei 2,9 GHz.

    Kann mir jemand helfen, das Problem zu lösen? Beim Dateityp Double tritt das Problem nicht auf, dafür ist die Größe des Feldes eingeschränkt.

    Dietrich

    Mittwoch, 9. November 2011 07:55

Antworten

  • Hallo in der Runde!

    In der Frage bin ich zu einer Erkenntnis gekommen, die mich zwar zur Lösung meines Vorhabens nicht befriedigt aber gegen technische Probleme dieser Art ist nun einmal kein Kraut gewachsen. Hier also, was ich mir überlegt habe:

    Eine Single-Variable hat die Möglichkeit positve und negative Gleitkommzahlen darzustellen, sie benutzt dazu 4 Bytes. Soviel ich mir zusammenreime in der Form smmm.mmmm.mmmm.mmmm.mmmm.mmmm.mzee.eeee wobei m (24-stellig) für Mantisse in der Form 1,xxx..., s für Vorzeichen Mantisse, z für Vorzeichen Exponent und e (6-stellig) für den Exponenten steht (an welcher Stelle die Vorzeichen stehen sei dahingestellt -- wahrscheinlich jeweils am Anfang --). Mit 24 Bit in der Mantisse lassen sich nun einmal nur Zahlen bis 2^24 - 1(=16.777.215) einschrittig darstellen. Darüber hinaus ist die Darstellung beschränkt, je nach der Potenz von 2 auf 2-er-, 4-er-, 8-er-Schritte usw. ; und mit 6 Bit im Exponenten stehten 2^6 (=64) Potenzen von 2 zur Verfügung (mit dem Vorzeichen des Exponeten stehen damit 128 Möglichkeiten zur Verfügung Potenzen von 2 Darzustellen, 63 positive (wenn man Null als positiv ansieht 64) und  64 negative. Ist in der Mantisse nur das kleinstwertige Bit besetzt also s0,00.0000.0000.0000.0000.0000.0000.0001 =2^-30 ergibt sich  nach dem Absolutwert als kleinste Single-Zahl ja wohl der Wert 2^-94(~5,04870979341E-29 in Dezimalschreibweise) und ist die Mantisse ganz gefüllt also s1,11.1111.1111.1111.1111.1111.1111.1111.1 also fast 2 -- aber noch nicht ganz -- die größte Single-Zahl ist demnach 2^64 - 2^33(~1,84467440651E19 in Dezimalschreibweise) -- aber nun einmal nicht mehr einschrittig --.

    Soweit meine -- hoffentlich nicht ganz fehlerhaften -- Überlegungen und nochmals vielen Dank für den Tip mit dem direkten Schreiben in die Zellen ohne 'Select', er hat mir geholfen, die Darstellung der Ergebnisse um ein Vielfaches zu beschleunigen!

    Dietrich Möhring


    Dietrich
    Freitag, 18. November 2011 05:20

Alle Antworten

  • Hallo Dietrich...

    bei mir verabschieden sich Excel 2007 und Excel 2010 mit einem StackHashxxx Fehler, entweder beim Ausführen oder Kompilieren, was wohl an der Größe des Arrays liegt.

    Excel 2003 lässt die Ausführung zu und produziert auch nicht die von Dir geschilderten Fehler. Unabhängig davon, ist es nicht optimal mit Select Anweisungen zu arbeiten. Anbei eine Alternative zum Schreiben Deiner Werte...

     

    Sub Test_2()
      
      Dim h   As Long
      Dim i   As Long
      Dim j   As Long
      Dim fn  As Long
      
      Dim a   As Long
      Dim b   As Long
      
      With ThisWorkbook.ActiveSheet
        
    .Columns("A:B").NumberFormat = "#,##0"

     a = 16777200 b = 16777230 For i = a To b 'Step 1 Prim(i) = i .Cells(i - a + 1, 1).Value = i .Cells(i - a + 1, 2).Value = Prim(i) Next i End With End Sub
    Gruß

     


    MVP Office System · Excel Formula Translator · www.excel-translator.de

    Mittwoch, 9. November 2011 08:58
  • Danke Mourad für den Tip mit der Darstellung im Workbook, sie ist ja superschnell

    aber die Probleme mit dem Dateityp 'Single' sind damit nicht gelöst. Wenn du ein 'kleines' Array dimensionierst und dort Zahlen über 2^24 (16.777.216) hieinschreibst und wieder ausliest, findest du nur noch 'gerade' Zahlen vor, das war eigentlich mein großes Anliegen. Die größe des Arrays macht mir keine Sorgen, mein Rechner nimmt Arrays mit einer Größe von über 100.000.000 Elementen an; wenn ich daß Array allerdings zu groß mache, steigt EXCEL beim Aufruf des Makros sangundklanglos aus.

    Tschüß

    Dietrich

    Freitag, 11. November 2011 10:24
  • Hallo in der Runde!

    In der Frage bin ich zu einer Erkenntnis gekommen, die mich zwar zur Lösung meines Vorhabens nicht befriedigt aber gegen technische Probleme dieser Art ist nun einmal kein Kraut gewachsen. Hier also, was ich mir überlegt habe:

    Eine Single-Variable hat die Möglichkeit positve und negative Gleitkommzahlen darzustellen, sie benutzt dazu 4 Bytes. Soviel ich mir zusammenreime in der Form smmm.mmmm.mmmm.mmmm.mmmm.mmmm.mzee.eeee wobei m (24-stellig) für Mantisse in der Form 1,xxx..., s für Vorzeichen Mantisse, z für Vorzeichen Exponent und e (6-stellig) für den Exponenten steht (an welcher Stelle die Vorzeichen stehen sei dahingestellt -- wahrscheinlich jeweils am Anfang --). Mit 24 Bit in der Mantisse lassen sich nun einmal nur Zahlen bis 2^24 - 1(=16.777.215) einschrittig darstellen. Darüber hinaus ist die Darstellung beschränkt, je nach der Potenz von 2 auf 2-er-, 4-er-, 8-er-Schritte usw. ; und mit 6 Bit im Exponenten stehten 2^6 (=64) Potenzen von 2 zur Verfügung (mit dem Vorzeichen des Exponeten stehen damit 128 Möglichkeiten zur Verfügung Potenzen von 2 Darzustellen, 63 positive (wenn man Null als positiv ansieht 64) und  64 negative. Ist in der Mantisse nur das kleinstwertige Bit besetzt also s0,00.0000.0000.0000.0000.0000.0000.0001 =2^-30 ergibt sich  nach dem Absolutwert als kleinste Single-Zahl ja wohl der Wert 2^-94(~5,04870979341E-29 in Dezimalschreibweise) und ist die Mantisse ganz gefüllt also s1,11.1111.1111.1111.1111.1111.1111.1111.1 also fast 2 -- aber noch nicht ganz -- die größte Single-Zahl ist demnach 2^64 - 2^33(~1,84467440651E19 in Dezimalschreibweise) -- aber nun einmal nicht mehr einschrittig --.

    Soweit meine -- hoffentlich nicht ganz fehlerhaften -- Überlegungen und nochmals vielen Dank für den Tip mit dem direkten Schreiben in die Zellen ohne 'Select', er hat mir geholfen, die Darstellung der Ergebnisse um ein Vielfaches zu beschleunigen!

    Dietrich Möhring


    Dietrich
    Freitag, 18. November 2011 05:20
  • Vielen Dank, Dietrich

    dass Du diese moegliche Loesung gepostet hast.

    VG/Bogdan


    Ich bin gerne bei den Foren. Es kommt von Herzen. Es wird aber keine implizite oder sonstige Garantie für die geposteten Antworte / Informationen gewährt. Hier auch die Forenregeln.
    Freitag, 18. November 2011 10:50