Thread: when is 4.2 = 4.20000000000.9

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    when is 4.2 = 4.20000000000.9

    ihave written a program that will give the root to a given power of a given number ie cube root of 125 is 5.

    that all works. i then decided that i didnt want a lot of trailing zeros so wrote the following
    Code:
    int main()
    {
        //declare variables
        double iBaseNum = 311.1696, iPowerNum = 0.25, iResult;
    
        iResult = Power( iBaseNum, iPowerNum );
    
        printf("%f to the power %f = ", iBaseNum, iPowerNum);
    
        PrinttoScreen( iResult );
    
    
        return 0;
    }
    
    double Power( double x, double y )
    {
        static int itmpPower = 0, i = 0;
        static double iBase = 1, presision = 0.000001;
        if ( y == 0 )
        {
            //anything to the power zero is 1 so return 1
            return 1;
        }//*
        else if ( y < 1 && y > 0 )
        {
            itmpPower = 1 / y;
            while ( i <= x )
            {
                iBase += 1;
                i = Power( iBase, itmpPower );
            }
            iBase -= 1;
    
            if ( x != Power( iBase, itmpPower ) )
            {
                printf("this run!\n");
                while ( Power( iBase, itmpPower ) < x )
                {
                    iBase += presision;
                }
            }
    
            return iBase;
        }//*/
        else if ( y == 1 )
        {
            //end of line so return base
            return x;
        }
    
        return x * Power( x, --y );
    }
    void PrinttoScreen ( double iResult )
    {
        int x, iCount = 0;
        double itmpResult;
    
        x = iResult;
        itmpResult = iResult;
    
        while ( x < itmpResult )
        {
            if ( iCount == 9 )
            {
                break;
            }
            itmpResult *= 10;
            x = itmpResult;
            iCount += 1;
        }
    
        switch ( iCount )
        {
            case 0:
                printf("%d\n", x);
                break;
    
            case 1:
                printf("%0.1f\n", iResult);
                break;
    
            case 2:
                printf("%0.2f\n", iResult);
                break;
    
            case 3:
                printf("%0.3f\n", iResult);
                break;
    
            case 4:
                printf("%0.4f\n", iResult);
                break;
    
            case 5:
                printf("%f0.5\n", iResult);
                break;
    
            case 6:
                printf("%f0.6\n", iResult);
                break;
    
            case 7:
                printf("%f0.7\n", iResult);
                break;
    
            case 8:
                printf("%f0.8\n", iResult);
                break;
    
            case 9:
                printf("%f0.9\n", iResult);
                break;
        }
    }
    if i enter 311.1696 to the power 0.25 (4th root) i get 4.2000000.9 not 4.2 i get there is prob some rounding errors in the registers etc however why is there 2 decimal places?

  2. #2
    Registered User Sir Galahad's Avatar
    Join Date
    Nov 2016
    Location
    The Round Table
    Posts
    277
    Quote Originally Posted by cooper1200 View Post
    ihave written a program that will give the root to a given power of a given number ie cube root of 125 is 5.

    that all works. i then decided that i didnt want a lot of trailing zeros so wrote the following
    Code:
    int main()
    {
        //declare variables
        double iBaseNum = 311.1696, iPowerNum = 0.25, iResult;
    
        iResult = Power( iBaseNum, iPowerNum );
    
        printf("%f to the power %f = ", iBaseNum, iPowerNum);
    
        PrinttoScreen( iResult );
    
    
        return 0;
    }
    
    double Power( double x, double y )
    {
        static int itmpPower = 0, i = 0;
        static double iBase = 1, presision = 0.000001;
        if ( y == 0 )
        {
            //anything to the power zero is 1 so return 1
            return 1;
        }//*
        else if ( y < 1 && y > 0 )
        {
            itmpPower = 1 / y;
            while ( i <= x )
            {
                iBase += 1;
                i = Power( iBase, itmpPower );
            }
            iBase -= 1;
    
            if ( x != Power( iBase, itmpPower ) )
            {
                printf("this run!\n");
                while ( Power( iBase, itmpPower ) < x )
                {
                    iBase += presision;
                }
            }
    
            return iBase;
        }//*/
        else if ( y == 1 )
        {
            //end of line so return base
            return x;
        }
    
        return x * Power( x, --y );
    }
    void PrinttoScreen ( double iResult )
    {
        int x, iCount = 0;
        double itmpResult;
    
        x = iResult;
        itmpResult = iResult;
    
        while ( x < itmpResult )
        {
            if ( iCount == 9 )
            {
                break;
            }
            itmpResult *= 10;
            x = itmpResult;
            iCount += 1;
        }
    
        switch ( iCount )
        {
            case 0:
                printf("%d\n", x);
                break;
    
            case 1:
                printf("%0.1f\n", iResult);
                break;
    
            case 2:
                printf("%0.2f\n", iResult);
                break;
    
            case 3:
                printf("%0.3f\n", iResult);
                break;
    
            case 4:
                printf("%0.4f\n", iResult);
                break;
    
            case 5:
                printf("%f0.5\n", iResult);
                break;
    
            case 6:
                printf("%f0.6\n", iResult);
                break;
    
            case 7:
                printf("%f0.7\n", iResult);
                break;
    
            case 8:
                printf("%f0.8\n", iResult);
                break;
    
            case 9:
                printf("%f0.9\n", iResult);
                break;
        }
    }
    if i enter 311.1696 to the power 0.25 (4th root) i get 4.2000000.9 not 4.2 i get there is prob some rounding errors in the registers etc however why is there 2 decimal places?
    It's an artifact. Your format string is all wrong. For doubles, use %g. The precision parameter goes between the % symbol and the format specifier.

    You do know that the pow function does calculate roots, right? Or are you just trying to reinvent the wheel here?

    Code:
    printf("%0.9g\n", pow(311.1696, 0.25));
    Last edited by Sir Galahad; 05-22-2023 at 08:51 AM.

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    yes but the exercise was to write a recursive function plus pow needs the math header it also doesnt take variables as an argument ie pow( x, y ) doesn't work

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    4.2 is not a representable floating point number.

    Floating-Point Calculator — 32-bit IEEE754
    4.2 converted to 32-bit floating point is
    010000001000011001100110011001102 (40866666H)
    The real value of this representation is 4.19999980926513672.

    4.2 converted to 64-bit floating point is
    01000000000100001100110011001100110011001100110011 001100110011012 (4010CCCCCCCCCC00H)
    The real value of this representation is 4.20000000000000018.

    The fraction is a repeating pattern, so it never ends, no matter how many bits you throw at it.
    So it's always going to round up or down to something close to, but not exactly 4.2.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by cooper1200 View Post
    it also doesnt take variables as an argument ie pow( x, y ) doesn't work
    I'm not sure why you would think that. It sure can take variables as arguments:

    Code:
    $ cat test-pow.c
    #include <math.h>
    #include <stdio.h>
    
    int main()
    {
        double x = 311.1696, y = 0.25;
        printf("%f\n", pow(x, y));
        return 0;
    }
    $ gcc -Wall -O2 -o test-pow test-pow.c -lm 
    $ ./test-pow 
    4.200000
    Also, you can condense your whole switch statement to something like this:

    Code:
    printf("%0.*f\n", iCount, iResult);
    The star (*) tells printf to take the next int argument for that value.

Popular pages Recent additions subscribe to a feed

Tags for this Thread