C pow() function printing gigantic numbers? [duplicate] - c

This question already has answers here:
c++ pow(2,1000) is normaly to big for double, but it's working. why?
(3 answers)
Closed 1 year ago.
sorry if this is a silly question, I am relatively new to C programming. Thus I have probably misunderstood something fundamental about variables/overflows.
I made this simple program and I can't explain the result
#include <stdio.h>
#include <math.h>
int main() {
double number = pow(2, 1000);
printf("%f\n", number);
}
The result of that (compiled with gcc) is a humongous number that should never fit in a variable of type double: 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376.000000
Usually when I try to assign a constant that is too large for it's type the compiler gives me an error.
So my question is: What is this number? Why am I not getting any errors? Is the variable number actually storing this value? Plainly, what's happening?

Doubles are not stored like integers. This page explains how double are representated in memory
Doubles contain 1 byte of sign, 11 bits for the exponent and 53 bits for the sigificand precision. Thus you can store numbers up to 1.7*10^308. Thus, your number cand be represented in a double (although with a limited precision). When printing it with %f, you just get its numerical value (approximated).

In C, double type can fit more than 300 decimal digits! A double is stored in 8 bytes, holding a number in the range 2.3E-308 to 1.7E+308 (15 decimal places accuracy).
Reference: https://www.tutorialspoint.com/cprogramming/c_data_types.htm

Related

Power function is returning different value in different text editor [duplicate]

This question already has an answer here:
Why the result of pow(10,2) 99 instead of 100? [duplicate]
(1 answer)
Closed last year.
I am trying to use the power function in a program but it is displaying/returning different values in the different text editors. Below is the simple code. I have typecasted since power returns double. In code blocks text editor, the power function is returning 100. But in an atom text editor, it is returning 99. But the same function in atom returns 100 if I replace count by 2. Am I missing installation of any extension in atom?. I don't know what is going on. Any suggestions/corrections are welcome.
#include <stdio.h>
#include <math.h>
int main(){
int count=2;
printf("%d",(int)pow(10,count));
return 0;
}
My guess is that this is due to a floating point rounding error. It may be that, while the real answer is 100, pow(10, 2) is returning 99.99998. When you convert that to an int, the decimal part gets chopped off.
What you can do is, instead of casting right away, run the result through the lround function (also found in math.h). This will return a long.
Avoid the pow function at all cost! It calculates a double raised with a double (for all possible values). This is an extremely complex calculation and it's done using an approximation. Rounding the result instead of using the default double to integer cast (which is defined as "round to zero") helps a bit, but not when the approximation errors more than 0.5.
If you intend to calculate "integer raised with an integer" I strongly suggest that you write your own that simply loops over the exponent -- it's way faster and it doesn't have any approximation problems.
(I say this as someone who has spent 25 years writing C compilers.)

Why do the square of input decreases by one when using pow function? [duplicate]

This question already has answers here:
unusual output from pow
(3 answers)
pow() function in C problems [duplicate]
(1 answer)
Why the result of pow(10,2) 99 instead of 100? [duplicate]
(1 answer)
What's wrong with long? Why is subtracting 1 automatically?
(1 answer)
Closed 2 years ago.
Here is a simple C program, which accepts a number from the user and results it's square.
#include <stdio.h>
#include <math.h>
int main()
{
int number;
int result;
printf("\nEnter the number\n");
scanf("%d",&number);
result=(pow(number,2));
printf("\nThe result is %d\n",result);
return 0;
}
The problem is, whenever i enter 5,25,26 etc as input, the output is 24,624,675 i.e. it decreases by 1 and this does not happen with all numbers. I am using CodeBlocks IDE. I figured out a fix for this problem but I want to know what is happening behind the scene, which is causing this error.
From this post, Sourav tells us:
pow() takes double arguments and returns a double.
If you store the return value into an int and print that, you may not get the desired result.
As for an explanation on why pow() is returning 1 less that you expect, see this post. Specifically:
pow() works with double numbers. These represent numbers of the form s * 2^e where s is a 53 bit integer. Therefore double can store all integers below 2^53, but only some integers above 2^53. In particular, it can only represent even numbers > 2^53, since for e > 0 the value is always a multiple of 2.

Floating point number is rounding off in C [duplicate]

This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 6 years ago.
i started learning c. Today, while i am working on a program, i found an interesting thing and i made another small program (similar to my issue) to check it.
#include<stdio.h>
int main(void)
{
float num1=867.0;
float num2=.6921;
printf("sum = %.4f \n",num1+num2);
return 0;
}
if i run the above program, i am getting 867.6921 as the answer. but if i changed the .4%f to %f the answer is changing to sum = 867.692078. why's the change in the output? Also, is there any way that i can get the answer without using the .4%f?
but if i changed the .4%f to %f the answer is changing to sum = 867.692078
printf rounds the result to that many digits after the floating point you specified, the default is .6. While rounding, it uses the current floating point rounding mode, the default is round to the nearest.
The float type has about seven digits of precision (can be anywhere from 6-9 digits). One alternative is to use g instead of f. This fixes the number of precise digits in the number, not just those after the decimal.
printf("sum = %.7g \n",num1+num2);
This produces output
sum = 867.6921
and will always give seven digits of precision for any input. Number formats would be like :
0.000000E+07
0000000
000000.0
00000.00
0000.000
000.0000
...etc

Factorial program in C is wrong after 20 [duplicate]

This question already has answers here:
Cannot calculate factorials bigger than 20! ! How to do so?
(7 answers)
Closed 6 years ago.
It works up until 20 but if 21 is entered it returns 1419745... when 21 factorial is actually 51090942171709440000. I'm assuming that this is because of the unsigned long maxing out but where does this wrong number (141...) come from and how can I allow the program to work out the factorial of larger numbers?
#include <stdio.h>
unsigned long fact(unsigned long input);
int main()
{
int input;
printf("Enter an integer to find the factorial of: ");
scanf(" %d", &input);
printf("The Factorial of %d = %lu\n" , input, fact(input));
return 0;
}
unsigned long fact(unsigned long input)
{
if (input == 0)
return 1;
else
return input * fact(input - 1);
}
This answers only to half of your question (why it works this way).
The result you get is 21! mod 2^64. This is because you are using a 64-bit system and 21! is greater than the greatest number that can be stored as unsigned integer on 64 bits.
All factorials you compute for values greater than or equal to 21 are wrong; they cannot be represented on 64-bit integers because they are longer than that.
You can try to use unsigned long long as the type of the values returned by function fact() (and change into the printf() format string %lu with %llu); it could help but it depends on some factors. It doesn't help on my architecture, for example.
You can find out if it can help you by checking the value returned by sizeof(unsigned long long). If if is 8 then you are out of luck. 20 is the largest number for what you can compute factorial on that system.
If your purpose is to compute factorials then you have to use a library that knows how to handle large numbers. However, if you need factorials for other computations (for example, for combinations) then you can try to avoid generating large numbers and find a way to match each multiplication with a division. This way the magnitude of the numbers you use is between the limits of 64-bit integers and you can go further than 21.
Or you can use double instead of integers and you are again back in business but with loss of precision. Large floating point numbers store correctly the magnitude of the number and its first digits. The last digits are lost.
I didn't program very much in C/C++ recently, I cannot recommend you a library that can help you do computations with large numbers :-(
The number comes from overflow. Unsigned arithmetic is done modulo (max value of that type), so a little maths should explain why you get the result you do.
The result of signed integer overflow is undefined so you could have got anything if you'd been using signed integers (though the chances are it'd have been exactly the same on a lot of systems)

How the float or double values are stored in variables in C? [duplicate]

This question already has answers here:
How to represent FLOAT number in memory in C
(11 answers)
Closed 7 years ago.
I was reading the way, how integers are stored in variables in c, that the last bit is used for the sign of the integer and the remaining bits are used to store the number.
But if we take a double variable and the long int variable in c, both has a size of 4 bytes but the float can store the very huge numbers up to a range of 1038 but long int of same size cant store such huge value.
I want to understand the mechanism which is used in storage in float.
The C language does not require any specific representation for floating point numbers.
Today, most C implementations are using IEEE floating numbers (exceptions are unusual, perhaps some Series Z mainframes from IBM).
Read http://floating-point-gui.de/
The complete explanation can be found here . Basically, the number is not fully stored, only approximately. The 32 bits are used to store as much precision as possible.

Resources