Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8952523
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T13:53:35+00:00 2026-06-15T13:53:35+00:00

Currently I calculate log as following: #define MAXLOG 1001 double myloglut[MAXLOG]; void MyLogCreate() {

  • 0

Currently I calculate log as following:

#define MAXLOG 1001
double myloglut[MAXLOG];
void MyLogCreate()
{
    int i;
    double exp, expinc;
    expinc = (2.0 - 0.1) / MAXLOG;
    for (i = 0, exp = 0.1; i <= MAXLOG; ++i, exp += expinc)
            myloglut[i] = log(exp);
    myloglut[478] = 0; // this one need to be precise
}

double MyLog(double v)
{
    int idx = (int)((MAXLOG*(v - 0.1)) / (2.0 - 0.1));
    return myloglut[idx];
}

As you can see I’m interested only in range 0.1 - 2.0. However, I need more precision around 0. How can I achieve that non linear calculation? Also is there any way to use some interpolation in this function for better precision?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T13:53:37+00:00Added an answer on June 15, 2026 at 1:53 pm

    Last version

    #include <stdio.h>                  // for input/output.
    #include <math.h>                   // for mathmatic functions (log, pow, etc.)
    
    // Values
    #define MAXELM 1000                 // Array size
    #define MINVAL 0.1                  // Minimum x value
    #define MAXVAL 1.9                  // Maximum x value
    #define EXPVAR 1.4                  // Exponent which makes the variation non linear. If set to 1, the variation will be linear.
    #define ACRTPT (MINVAL + MAXVAL)/2  // Accurate point. This value is used to know where to compute with maximum accuracy. Can be set to a fixed value.
    // Behavior
    #define STRICT 0                    // if TRUE: Return -1 instead of the floored (or closest if out of range) offset when (x) hasn't been calculated for this value.
    #define PNTALL 0                    // if TRUE: Print all the calculated values.
    #define ASKFOR 1                    // if TRUE: Ask for a x value then print the calculated ln value for it.
    
    // Global vars
    double results[MAXELM];             // Array to store computed values.
    
    // Func: offset to var conversion
    double getvar(int offset)
    {
        double x = (double)MINVAL + ((double)MAXVAL - (double)MINVAL) * (double)offset / (double)MAXELM;
    
        if(x >= (double)ACRTPT)
            x = pow(x - (double)ACRTPT, (double)EXPVAR) + (double)ACRTPT;
        else
            x = -pow((double)ACRTPT - x, (double)EXPVAR) + (double)ACRTPT;
        // This ^ is the equation used when NONLIN = 1; to have a non linear repartition. Feel free to change it. The inverse equation is in `int getoffset(double)`.
        return x;
    }
    
    // Func: var to offset conversion
    int getoffset(double var)
    {
        double x = var;
    
        if(x >= (double)ACRTPT)
            x = pow(x - (double)ACRTPT, 1.0/(double)EXPVAR) + (double)ACRTPT;
        else
            x = -pow((double)ACRTPT - x, 1.0/(double)EXPVAR) + (double)ACRTPT;
        // This ^ is the equation used when NONLIN = 1; to calculate offset with a non linear repartition. Feel free to change it (but it must be the inverse of the one in
        // `double getvar(int)` for this to work.). These equations are tied, so you cannot modify one without modifying the other. They are here because
        // `pow(negative, non-integer)` always returns `-nan` instead of the correct value. This 'trick' uses the fact that (-x)^(1/3) == -(x^(1/3)) to cicumvent the
        // limitation.
    
        int offset = (x - (double)MINVAL) * (double)MAXELM / ((double)MAXVAL - (double)MINVAL);
    #if STRICT
        if(getvar(offset) != var)
            return -1;
        return (offset < 0)?-1:(offset > (MAXELM - 1))?-1:offset;
    #else
        return (offset < 0)?0:(offset > (MAXELM - 1))?MAXELM - 1:offset;
    #endif
    }
    
    // Func: main.
    int main(int argc, char* argv[])
    {
        int offset;
        for(offset = 0; offset < MAXELM; offset++)
            results[offset] = log(getvar(offset));
    
    #if PNTALL
        for(offset = 0; offset < MAXELM; offset++)
        {
            printf("[log(%lf) = %lf] ", getvar(offset), results[offset]);
            if(!((offset + 1) % 6))
                printf("\n");
        }
        printf("\n");
    #endif
    
    #if ASKFOR
        double x;
        printf("log(x) for x = ");
        scanf("%lf", &x);
        if((offset = getoffset(x)) < 0)
            printf("ERROR: Value for x = %lf hasn't been calculated\n", x);
        else
            printf("results[%d]: log(%lf) = %lf\n", offset, getvar(offset), results[offset]);
    #endif
    
        return 0;
    }
    

    Last versions’s characteristics:

    • Uses a fixed size array.
    • Computes ONLY the stored values (won’t calculate multiple values for one array cell).
    • Uses functions to get offset from value and value from offset, so you don’t have to store the values of which the log has been calculated.

    Advantages over the last version:

    • Does not use cbrt, uses pow instead.
    • Allows to specify the growth of calculus variable at compilation time. (So the values are more or less grouped around the accurate point (ACRTPT))

    Third version

    #include <stdio.h>                  // for input/output.
    #include <math.h>                   // for mathmatic functions (log, pow, etc.)
    
    // Values
    #define MAXELM 1000                 // Array size
    #define MINVAL 0.1                  // Minimum x value
    #define MAXVAL 1.9                  // Maximum x value
    #define ACRTPT (MINVAL + MAXVAL)/2  // Accurate point. This value is used to know where to compute with maximum accuracy. Can be set to a fixed value.
    // Behavior
    #define NONLIN 1                    // if TRUE: Calculate log values with a quadratic distribution instead of linear distribution.
    #define STRICT 1                    // if TRUE: Return -1 instead of the floored (or closest if out of range) offset when (x) hasn't been calculated for this value.
    #define PNTALL 0                    // if TRUE: Print all the calculated values.
    #define ASKFOR 1                    // if TRUE: Ask for a x value then print the calculated ln value for it.
    
    // Global vars
    double results[MAXELM];             // Array to store computed values.
    
    // Func: offset to var conversion
    double getvar(int offset)
    {
        double x = (double)MINVAL + ((double)MAXVAL - (double)MINVAL) * (double)offset / (double)MAXELM;
    #if NONLIN
        x = pow((x - ACRTPT), 3) + ACRTPT;
        // This ^ is the equation used when NONLIN = 1; to have a non linear repartition. Feel free to change it. The inverse equation is in `int getoffset(double)`.
    #endif
        return x;
    }
    
    // Func: var to offset conversion
    int getoffset(double var)
    {
    #if NONLIN
        int offset = ((
            cbrt(var - ACRTPT) + ACRTPT
        // This ^ is the equation used when NONLIN = 1; to calculate offset with a non linear repartition. Feel free to change it (but it must be the inverse of the one in
        // `double getvar(int)` for this to work.)
                        ) - (double)MINVAL) * (double)MAXELM / ((double)MAXVAL - (double)MINVAL);
    #else
        int offset = (var - (double)MINVAL) * (double)MAXELM / ((double)MAXVAL - (double)MINVAL);
    #endif
    #if STRICT
        if(getvar(offset) != var)
            return -1;
        return (offset < 0)?-1:(offset > (MAXELM - 1))?-1:offset;
    #else
        return (offset < 0)?0:(offset > (MAXELM - 1))?MAXELM - 1:offset;
    #endif
    }
    
    // Func: main.
    int main(int argc, char* argv[])
    {
        int offset;
        for(offset = 0; offset < MAXELM; offset++)
            results[offset] = log(getvar(offset));
    
    #if PNTALL
        for(offset = 0; offset < MAXELM; offset++)
        {
            printf("[log(%lf) = %lf] ", getvar(offset), results[offset]);
            if(!((offset + 1) % 6))
                printf("\n");
        }
        printf("\n");
    #endif
    
    #if ASKFOR
        double x;
        printf("log(x) for x = ");
        scanf("%lf", &x);
        if((offset = getoffset(x)) < 0)
            printf("ERROR: Value for x = %lf hasn't been calculated\n", x);
        else
            printf("results[%d]: log(%lf) = %lf\n", offset, getvar(offset), results[offset]);
    #endif
    
        return 0;
    }
    

    This version is cleaner and easier to maintain than the previous ones. If you need anything else, please leave a comment.

    You can configure its behavior using the macros at the top of the file.

    Caracteristics:

    • Uses a fixed size array.
    • Computes ONLY the stored values (won’t calculate multiple values for one array cell).
    • Uses functions to get offset from value and value from offset, so you don’t have to store the values of which the log has been calculated.

    Second version

    Well, here is my second solution. See below it for the original comment.

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define MIN_INC 0.001    // This is the minimum increment. If its set to 0, when tmp will be equal to avg, it will never leave this state, since INC_MUL * (tmp - avg)^2 will be 0.
    #define INC_MUL 0.2      // This is a number which influences the precision you will get. The smaller it is, the more precise you will be, and the greater will be your result array cardinality.
    
    typedef struct {
        double offset;
        double value;    // value = log(offset). Since the results are not linarly widespread, this is pretty important.
    } logCalc;
    
    // Here, we need to use a pointer on a logCalc pointer, since we want to actually SET the address of the logCalc pointer, not the address of one of its copies.
    int MyLogCreate(logCalc** arr, double min, double max)
    {
        if((*arr) != NULL)
            return 0;
        unsigned int i = 0;
        double tmp, avg = (max + min) / 2.0;
        for( ; min < avg; min += (INC_MUL * ((avg - min) * (avg - min)) + MIN_INC))
        {
            (*arr) = (logCalc*)realloc((*arr), sizeof(logCalc) * (i + 1));
            (*arr)[i].offset  = min;
            (*arr)[i++].value = log(min);
        }
        for(tmp = avg ; tmp < max; tmp += (INC_MUL * ((tmp - avg) * (tmp - avg)) + MIN_INC))
        {
            (*arr) = (logCalc*)realloc((*arr), sizeof(logCalc) * (i + 1));
            (*arr)[i].offset  = tmp;
            (*arr)[i++].value = log(tmp);
        }
        return i;
    }
    
    int main(int argc, char** argv)
    {
        logCalc *myloglut = NULL;
        unsigned int i,
            t = MyLogCreate(&myloglut, .1, 1.9);
        for(i = 0; i < (t-1); i++)
        {
            printf("[log(%lf) = %lf], ", myloglut[i].offset, myloglut[i].value);
            if(!((i+1)%6))         // Change 6 to what's best for your terminal $COLUMNS
                printf("\n");
        }
        printf("\n");
        free(myloglut);
        return 0;
    }
    

    Original comment

    The linearity of your calculation comes from the fact that you’re using a linear increment. On each iteration of your for loop, you increment exp by (2.0 - 0.1) / MAXLOG.

    To get more precise values around 0, you will need:

    1. To define a larger range – a larger array – (to be able to store more values around 0)
    2. To use a non-linear increment. This increment will probably be dependent on i (or on exp, depending on how you do it), so you know precisely the “offset” of the number you are trying to calculate (and the amount you need to increment exp with). Of course, you will calculate more results around 0.

    Here is my current implementation of it:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define CALCULATE_UNTIL 2.0
    #define PRECISE_UNTIL   1.0
    
    typedef struct {
        double offset;
        double value;
    } logCalc;
    
    logCalc *myloglut = NULL;
    
    int MyLogCreate()
    {
        double exp = 0.1;
        int i;
        for (i = 0; exp <= CALCULATE_UNTIL; exp += (exp < PRECISE_UNTIL)?0.0001898:0.001898)
        {
            myloglut = realloc(myloglut, sizeof(logCalc) * (i + 1));
            myloglut[i].offset = exp;
            myloglut[i++].value = (i == 4780)?0:log(exp);
        }
        return i; // So you know how big the array is. Don't forget to free(myloglut); at the end of your code.
    }
    
    int main(int argc, char** argv)
    {
        int i,
        t = MyLogCreate();
        for(i = 0; i < t; i++)
        {
            printf("[log(%lf) = %lf], ", myloglut[i].offset, myloglut[i].value);
            if(!(i%6))    // For formatting purposes.
                printf("\n");
        }
        printf("\n");
        free(myloglut);
        return 0;
    }
    

    I’ve created a new type in order to store the value of exp too, which could be useful for knowing what value the result is the log of.

    Update: I’m not sure about what you want to do. Do you want to be precise around log(x) = 0 or around x = 0? On the first case, I might have to re-write the code again for it to work as you want. Also, do you want the results to be more precise at it gets close to 0, or do you want the results to be more precise in a given range (as it is now)?

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm currently working on the following code: for (double i = 0.00; i <
I'm currently using this code to calculate the sunrise / sunset times. (To be
I'm currently working on a game in Java and I want to calculate the
How to correctly convert the following C++ into C#? //-------------------------------------------------------------------- // Calculate a 16-bit
I have following code for opening all files: int ret= open(zFile, flags, mode); posix_fadvise
I am currently working on a data management system that needs to calculate huge
I am currently using cast on a melted table to calculate the total of
In a project I'm currently working on I have to calculate the 5 moments
I'm using jQuery to calculate the amount of the page that is currently scrolled,
I am currently working on a package subscription manager where I have to calculate

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.