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:
- 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 evenlong long int
- Use long arithmetic functions, as @rustyx sayed. You can write your own with vector, or find and include library.
- 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
How to Compile SQLite with Icu
Colour Output of Program Run Under Bash
Memory Stability of a C++ Application in Linux
How to Know If One Shared Library Depends on Another Shared Library or Not
Opencv Videocapture Lag Due to the Capture Buffer
/Usr/Lib64/Libstdc++.So.6: Version 'Glibcxx_3.4.15' Not Found
How to Get a List of Installed True Type Fonts on Linux Using C or C++
Pthread Condition Variables Not Signalling Even Though Set to Pthread_Process_Shared
How to Find What Version of Libstdc++ Library Is Installed on Your Linux MAChine
Headers Including Each Other in C++
External Library Throws Undefined Reference Errors in Qt Creator
How to Correctly Interpose Malloc Allowing for Ld_Preload Chaining
Deploying Qt Applications in Linux Properly
Why Can't We Pass Arrays to Function by Value
Destroy and Then Construct New Object Using the Same Variable