Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
885 views
in Technique[技术] by (71.8m points)

c - How to make math logarithm functions in C99?

I'm finally back at building my functions, which is what I'm doing before making the actual BPML language. In Part 3 - Math, I want to make some logarithm functions.

I never knew what logarithm functions were at the very beginning, but as I went deeper, I learned it and made this:

float log_num(int num) {
    int mult;
    float result = 0;
    for (int i = 0; ; i++) {
        mult = 10 ^ i;
        if (mult >= num) {
            result = i;
            break;
        }
    }
    return result;
}

log_num only supports int and float and double will have their separate ones.

Now I got 2 problems with this function:

  1. When I tried to run it and use 100 as the number in the function, the result should've been 2.00, but it gave me 1.00.
  2. Since the value to be returned is a float, I want the function to actually give me different values if it is not a power of 10. An example of it is 2 = 0.30102999566398119521373889472449.

Q: How do I fix problem 1 and how do I make the function work as how I explained in problem 2?

I want to make the function from scratch and not relying on other functions.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Q: How do I fix problem 1 ... ?

10 ^ i is 10 exclusive-or'ed with i. It is not 10i.

To find the integer portion of log10(num)

int i_portion = 0;
if (num <= 0) Handle_elsewhere();
else {
  int i_portion = 0;
  int n = num;
  while (n >= 10) {
    n /= 10;
    i_portion++;
  } 
  printf("%d
", i_portion);
} 

Q: ... and how do I make the function work as how I explained in problem 2?

Below is a quick solution since C99:

#include <math.h>
float log_num(int num) {
  return log10f(num);
}

To code without <math.h> is fairly broad. For efficient construction, we need design parameters.

First, be clear about base. The standard log() is base e, not base 10 as the question implies.

Corner/Error handling: How do you want to handle negative inputs? Logany positive base(0) is usually returned as -∞. For finite positive values, no range issues. What should be returned for +∞, perhaps +∞? What should be returned for NaN, perhaps NaN?

Accuracy/precision: Do you want the best result or willing to given up accuracy for speed or small code foot-print? Why return float versus the more common double?

Performance: simply code that is of poor run-time performance OK? Just code per Logarithm Calculation. Since the goal includes my_log_i(int), my_log_f(float), my_log_d(double), for now, just code my_log_d(double) and have the the others call it.

Portability - how portable?


Sure we can code up a simply float my_log_10(int), but without the design details, the result would be lacking in many ways.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...