-1

I am making a new project in c and the function pow "does not work".What can I do to fix?

It functions actually 2 to the power of 10 but 10 to the power of 1 comes out 99

#include <stdio.h>
#include <math.h>

int main() {
    int res = pow(10, 2);
    printf("%d", res);
    return 0;
}

i expect the output of to be 100 but the output is 99

Sam Mason
  • 15,216
  • 1
  • 41
  • 60
  • 2
    Look at the result as a floating point value. What is the assignment to an “int” variable doing to it, and how does it explain the behavior? (Tip: enable and read compiler warnings.) – user2864740 Jan 06 '19 at 00:51
  • 2
    Also, please only use relevant tags. The question contains C code, and should thus not be tagged with “css” or even “javascript” as they are completely unrelated. – user2864740 Jan 06 '19 at 00:54
  • Yes, i tried it, it did work, but this is a part of a big project, so must this mean that i must change all my data types from integers to floating points? – Arlindi Frakulla Jan 06 '19 at 00:57
  • 1
    No- it means you have to be aware what is happening, the desired outcome and limitations, and code accordingly. In the specific case shown, see round() as a possible way to “fix” the expectations. Or, just use 10 * 10.. :} – user2864740 Jan 06 '19 at 00:57
  • 2
    Or, for this particular case, look up or write a substitute for `pow()` that takes `int` parameters and uses only integer arithmetic for its computations. And for computing small integer powers, use multiplication instead of `pow()`, even when the base is *non*-integer. – John Bollinger Jan 06 '19 at 01:02
  • 1
    [What Every Programmer Should Know About Floating-Point Arithmetic](http://www.phys.uconn.edu/~rozman/Courses/P2200_15F/downloads/floating-point-guide-2015-10-15.pdf) See also: [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) and [Why Are Floating Point Numbers Inaccurate?](https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate) – David C. Rankin Jan 06 '19 at 02:39

1 Answers1

6

pow(10, 2) yields a value slightly under 100 because it is a low-quality implementation of pow that does not return a good result.

pow is a difficult function to implement, and all commercial implementations produce many results that are inaccurate to some degree. However, good implementations make an effort to get certain cases exactly correct, including cases where the result is exactly an integer (or, for that matter, is rational).

In pow(base, exp), if exp is known to be 2 at compile time, base*base should be used instead—it is fast and accurate and avoids the pow problem. If exp is not known to be two at compile time, the code must be designed to tolerate inaccuracies in pow or other adjustments must be made. (Further advice could be given to questions that are more specific about the circumstances or requirements.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • So, what could be the best solution? To make all integers into floating points?So that I could get an exact result – Arlindi Frakulla Jan 06 '19 at 01:02
  • 3
    @ArlindiFrakulla: As my answer states, further advice could be given to questions that are more specific about the circumstances or requirements. If `exp` is known to be two, use `base*base` and do not use `pow`. If that is not the case, then (a) What cases do you need to support? Is `base` always an integer? Is `exp` always a non-negative integer? (b) Why do you need the power? What further arithmetic will it be used in—why does it need to be exact instead of approximate? Good solutions depend on specific requirements. You have to write more about the situation. – Eric Postpischil Jan 06 '19 at 01:06
  • 2
    No, @ArlindiFrakulla, converting to floating point and back is what got you in trouble. Doing more of that is not a solution. FP arithmetic and functions in general produce *in*exact results -- sometimes, as in your case even when the exact mathematical result is representable. – John Bollinger Jan 06 '19 at 01:06
  • 2
    @JohnBollinger: Floating-point is not the problem here. A poor implementation of `pow` is the problem. If you had an integer `ipow(base, exponent)` that gave an inaccurate result when the exact result was representable, you would not say that integer arithmetic is what got you in trouble. You would say bad software is what got you in trouble. That is the situation here: A good `pow` works fine for this. A bad `pow` implementation caused the problem. – Eric Postpischil Jan 06 '19 at 01:07
  • My actual project is to make the program as short as possible, but the only problem that I have, is with the power #include #include int main(){ long int n,count = 0; scanf("%li", &n); while(n != 0){ n = n/10; count++; }printf("Biggest number:%i",pow(10,count)); } – Arlindi Frakulla Jan 06 '19 at 01:10
  • 1
    @ArlindiFrakulla: For the situation you describe, you should not use `pow`. Simply define `long p = 1;` and multiply `p` by 10 in each iteration. This is fast, correct, simple, and easy to read and understand. (Shortness is not a good goal—it can be a proxy for simple and easy to read and understand, but being actually simple and easy to read and understand is better than short.) If you are in some contest situation where shortness is the arbitrary goal, well, you might want to consider using a different C implementation, one with a good `pow` implementation. – Eric Postpischil Jan 06 '19 at 01:12
  • 1
    That's a rather narrow view, @EricPostpischil. Involving a function that computes a floating-point result from floating-point arguments is a poor strategy when an exact result is desired, exactly because it affords the possibility of being bitten by behavior such as the OP observed. Sure, he would not have had a problem if his `pow()` behaved differently, but that's pretty much self-evident, and it doesn't generalize very usefully. – John Bollinger Jan 06 '19 at 01:18
  • 1
    @JohnBollinger: It generalizes fine. Sometimes I handle troublesome `int32_t` arithmetic by using `int64_t`. If an `int64_t` operation failed to give a mathematically correct result even though it were representable in the type, I would blame the operation and not the `int64_t` format, and I would not respond by telling people to avoid `int64_t` because it is a poor strategy. Floating-point is not a boogie man. It is just a method for computing, like integer arithmetic, pointers, data structures, sorting, databases, or whatever. If you understand it, it works fine. – Eric Postpischil Jan 06 '19 at 01:27
  • @JohnBollinger: If any other routines—`qsort`, `fprintf`, whatever—return wrong results, we complain and expect better. `pow` is indeed hard to get correct—nobody has implemented a correctly rounded version with known bounded run time—but the rational cases can be made correct, and that is a standard we ought to expect. The advice to avoid floating-point, when we would not hesitate to tell users to take advantage of any other computational techniques that would solve the problem—is the narrow view. – Eric Postpischil Jan 06 '19 at 01:29
  • 2
    @JohnBollinger: In Stack Overflow questions, we get unending repetitions of integer arithmetic failures—missing fractions in divisions, overflows, type issues—yet few people blame integer arithmetic for these. Most take the approach of teaching people to use integer arithmetic correctly. Why is floating-point treated differently? It is just computing. Learn to use it. – Eric Postpischil Jan 06 '19 at 01:33
  • Thanks for your help guys, all props to you ,I actually solved the problem.@EricPostpischil and @JohnBollinger – Arlindi Frakulla Jan 06 '19 at 01:36
  • #include int main(){ long int n=0,count = 0,res=1; scanf("%li", &n); while(n != 0){ n = n/10; count++; }for(count;count>0;count--){ res=res*10; }printf("Biggest number:%i",res); return 0; } – Arlindi Frakulla Jan 06 '19 at 01:37