log 10 berechnen


  • Gesperrt

    Huhu... 🙂

    Wie muss ich hier die Grenze (zurzeit 25) wählen, damit alle float-Bits, bis auf das LSB, korrekt gesetzt werden? Und wie viele Bits hat ein float überhaupt?

    #include <stdio.h>
    
    float calc_log_10(const unsigned int x)
    {
        if (x == 0)
        {
            return 0;
        }
    
        unsigned int part_a = x;
        float part_b = x;
        unsigned int a = 0;
        while (part_a >= 10)
        {
            part_a /= 10;
            part_b /= 10;
            a++;
        }
    
        float result = a;
        float frac = 0.5;
        for (int i = 0; i < 25; i++)
        {
            part_b *= part_b;
            if (part_b > 10)
            {
                part_b /= 10;
                result += frac;
            }
            frac *= 0.5;
        }
    
        return result;
    }
    
    int main(int argc, char const *argv[])
    {
        printf("%f\n", calc_log_10(1));
        printf("%f\n", calc_log_10(10));
        printf("%f\n", calc_log_10(1000));
        printf("%f\n", calc_log_10(1111));
        return 0;
    }
    

    math.h ist nicht erlaubt.



  • @nameName sagte in log 10 berechnen:

    Und wie viele Bits hat ein float überhaupt?

    Kannst du aus sizeof(float) und CHAR_BIT berechnen.
    Schau dir überhaupt <limits.h> an.

    Du willst aber an die 25, die ist in FLT_MANT_DIG aus <float.h> definiert.

    Es wäre aber auch möglich schon vorher abzubrechen, wenn sich der Wert nicht mehr ändert.

    IEEE 754 kennt auch INF, -INF für +/- Unendlich und NAN für Not a Number.
    Denn Zeile 7 ist falsch.

    Zum spielen mit Fließkommazahlen: https://www.h-schmidt.net/FloatConverter/IEEE754de.html


  • Gesperrt

    Vielen Dank... Ja, der Rückgabewert in Zeile 7 für x=0 ist falsch, ich wusste nicht, dass auch nan möglich ist...

    Werde mich noch mal in Ruhe näher damit befassen


  • Gesperrt

    @DirkB

    Jetzt müsste es richtig sein, und auch immer anhalten (hoffe ich):

    #include <stdio.h>
    #include <math.h>
    
    #define MY_NAN 0.0 / 0.0
    
    double calc_log_10(const unsigned int x)
    {
        if (x == 0)
        {
            return MY_NAN;
        }
    
        unsigned int part_a = x;
        double part_b = x;
        unsigned int a = 0;
        while (part_a >= 10)
        {
            part_a /= 10;
            part_b /= 10;
            a++;
        }
    
        double result = a;
        double frac = 0.5;
        for (int i = 0; frac != 0; i++)
        {
            part_b *= part_b;
            if (part_b > 10)
            {
                part_b /= 10;
                result += frac;
            }
            frac *= 0.5;
        }
    
        return result;
    }
    
    int main(int argc, char const *argv[])
    {
        // Some test cases
        int index = 1;
        for (size_t i = 0; i <= 100; i++)
        {
            double f1 = calc_log_10(i);
            double f2 = log10(i);
            int c1 = f1 == f2 || isnan(f1) || nextafter(f1, 0) == f2 || nextafter(f2, 0) == f1;
            printf("%d: %lf %lf %d\n", index++, f1, f2, c1);
            if (!c1)
            {
                break;
            }
        }
        for (size_t i = 9999; i <= 10003; i++)
        {
            double f1 = calc_log_10(i);
            double f2 = log10(i);
            int c1 = f1 == f2 || isnan(f1) || nextafter(f1, 0) == f2 || nextafter(f2, 0) == f1;
            printf("%d: %f %f %d\n", index++, f1, f2, c1);
            if (!c1)
            {
                break;
            }
        }
        return 0;
    }
    

    log10 liefert aber einfach -inf zurück, und nan ist nicht gleich nan... 🙈 (deshalb sehen die Vergleiche in Zeile 47 und 58 so seltsam aus...) und das letzte Bit mag mich nicht.



  • den ausdruck in zeile 4 solltest du in klammern setzen



  • Danke für den Hinweis. Werde ich mal noch einbauen ... insbesondere, wenn Terme unübersichtlich werden, ist das nützlich.

    Schade nur, dass ich wieder gesperrt wurde (nachdem ich auf Nonsens im anderen Thema reagiert hatte...). Vermutlich wird dieser Account auch nicht lange da sein.



  • @omggg sagte in log 10 berechnen:

    Schade nur, dass ich wieder gesperrt wurde (nachdem ich auf Nonsens im anderen Thema reagiert hatte...). Vermutlich wird dieser Account auch nicht lange da sein.

    Liegt in deiner Hand. Es gibt Gründe dafür, dass du ständig gesperrt wirst.



  • @DocShoe sagte in log 10 berechnen:

    Es gibt Gründe dafür, dass du ständig gesperrt wirst.

    Zählt korrektes Verhalten auch dazu? 😅 Aber hab es verstanden. Je mehr Freunde man hat, desto mehr hassen einen... Das heißt, pro vernünftige Antwort auf eine meiner Fragen gibt es mindestens ein, die total daneben ist. Schönen Abend allen.


Anmelden zum Antworten