Why Does Gcc Compiler Output Pow(10,2) as 99 Not 100

Why does gcc compiler output pow(10,2) as 99 not 100?

Because of integer truncation. pow() returns a floating point value, and due to floating point arithmetic, it is probably ~ 99.999...; however, due to integer truncation, even 99.999... gets truncated down to 99.

I got different results with pow(10,2) and pow(10,j), j=2;

What's going on is that you have a C implementation whose standard library has a very low quality implementation of pow which is returning inexact results even when the exact result is representable in the type (double). The call to pow(10,2) seems to producing the value just below 100.0, which, when rounded to an integer, yields 99. The reason you don't see this when the arguments are constant is that the compiler took the liberty to optimize out the call alltogether and replace it with a constant 100 at compiletime.

If your intent is to do integer powers, don't use the pow function. Write a proper integer power function, or when the exponent is known, just write out the multiplication directly.

Why is the value of my sum lower than it is supposed to be by 1?

Your program gets 152 for sum because your C implementation has a sub-par implementation of pow.

The proper return value of pow(5, 3) is 125, but your C implementation returns something like 124.9999999999999857891452847979962825775146484375. In sum += pow(digit,3);, sum has type int, so the result of the addition is converted to an integer, which results in truncation of the fractional part.

This occurs because pow is implemented with floating-point arithmetic, and the implementation does not take care to return a good quality result. pow is generally difficult to implement, but it is feasible to implement pow with an error of less than one unit of least precision (ULP). When this is done, exactly correct results are returned in all cases where the mathematical result is representable.

To avoid this in your program, do not use the floating-point pow function. For this simple program, write your own “integer pow” function.

Something wrong with assigning the value of the equation to a variable

It seems that your pow implementation is inaccurate for these values. I have managed to get the same results as you by forcefully making pow(10, power) inaccurate.

In case of the first variant in your code:

std::cout << n + el * pow(10, power) << std::endl;

The value of the expression is slightly less than 500. You can verify this by

 std::cout.precision(20);
std::cout << n + el * pow(10, power) << std::endl;

I suspect that this will print something like:

499.99999499999995578

(Note that since your original code prints numbers with a lower precision, you are deceived to believe that the expression results with 500. However, the actual value is slightly smaller).

In the case of the second line of code:

n = n + el * pow(10, power);

the 499.99999499999995578 is assigned to an int variable, truncating the fraction and leaving you with 499. Everything goes south after that.

NOTE:

I don't think that IEEE 754 dictates how pow(10, 2) should be implemented, and in theory it can be implemented using eln(10)*2, which introduces inaccuracies. Moreover C++ does not mandates IEEE 754 conformance. This means that pow(10,2) could be inaccurate on some systems and make a small error down or up, just like in your case.

Solution:

Don't use pow at all, or else use round(pow(10, power)). In your case, it is better to use regular integer multiplication by 10.

Loss of precision with pow function when surpassing 10^10 limit?

The main reason of problems is pow() function. It works with double, not int. Loss of accuracy is price for representing huge numbers.
There are 3 way's to solve problem:

  1. For small n you can make your own long long int pow(int x, int pow) function. But there is problem, that we can overflow even long long int
  2. Use long arithmetic functions, as @rustyx sayed. You can write your own with vector, or find and include library.
  3. There is Math solution specific for topic's task. It solves the big numbers problem.
    You can write your formula like
    ((10^n) - 1) * (10^n) - (10^m - 1) * (10^m)) / 2 , (here m = n-1)
    Then multiply numbers in numerator. Regroup them. Extract common multiples 10^(n-1). And then you can see, that answer have a structure:
    X9...9Y0...0 for big enought n, where letter X and Y are constants.
    So, you can just print the answer "string" without calculating.


Related Topics



Leave a reply



Submit