Why is this power calculating function crashing? - c

I tried following function (as suggested on these forums) to calculate power. However, it is causing program to hang up.
static long ipow(int b, int e) {
long r = 1;
while (e--) r *= b;
return r;
}
double cfilefn(int a, int b, int c) {
return (ipow(a, b) / (double)c);
}
cfilefn(2,3,4);
The function looks all right. Where is the error and how can it be solved?

The ipow function will misbehave if the second argument is a negative number: it will run for a while and have implementation defined behavior when e reaches INT_MIN. You should modify the test while (e--) r *= b; as:
static long ipow(int b, int e) {
long r = 1;
while (e-- > 0)
r *= b;
return r;
}
Note however that ipow will cause arithmetic overflow for moderately large values of e and since you want a double result from cfilefn, you should use double arithmetics for the power function:
#include <math.h>
double cfilefn(int a, int b, int c) {
return pow(a, b) / c;
}

Related

Why is my power function not working properly here?

I've tried changing variable types but this is still not working.
double power(double a, long long b){
while(b>1){
a *= a;
b--;
}
return a;
}
Your code won't run properly when b>2 because when you're doing a = a*a; the second time it won't be a^3 but a^4 and the next time it will be a^8 and so on.
The right code would be something like this below:
double power(double a, long long b){
double k = 1;
while(b>0){
k *= a;
b--;
}
return k;
}
You're changing a on every iteration. Say you call it like power(2, 3).
First you do 2 * 2 and assign this to a, which becomes 4.
Next iteration, you'll do again a * a which is 4 * 4. Just keep the result in a variable and don't change the arguments:
double power(double a, long long b){
double r = a;
while(b>1){
r *= a;
b--;
}
return r;
}
you are changing the variable a and it courses the defects. what you can do instead is
double power(double base, double exp)
{
double result = 1;
for(int i = 0; i < exp; i++)
{
result *= base;
}
return result;
}

Getting wrong square-root estimation

I have written a program in C which is calculating for me the square root with the heron procedure. x is my number, r is estimated value and steps are steps. I want to output the difference between the exact value and the value obtained by the heron method. But it seems that my function is not correct. For my calculated value I get no value. Can anyone help me?
#include <stdio.h>
#include <math.h>
int heron (x, r, steps)
{
int k = 0;
double xold, xnew;
double rel_error = 1.0;
while(k <= steps && rel_error > 1e-4) {
++k;
xnew = .5 * (xold + x / xold);
rel_error = (xnew - xold) / xnew;
if(rel_error < 0)
rel_error = -rel_error;
xold = xnew;
}
printf("exact value: %.10f\n", sqrt(x));
return (xnew);
}
int main()
{
int x=4, r=10, steps=50;
printf("%f\n", heron(x, r, steps));
return 0;
}
Change int heron (x, r, steps) to double heron(double x, double r, int steps). You need to declare the types of the parameters, and the function works with floating-point values, so it ought to return float or double, not int, and x and r should be double.
Change double xold , xnew; to double xold = r, xnew;. xold must be initialized before it is used.
Change return sqrt(x); to return xold; to return the value that the function calculated.
With this prefix
int heron (x, r, steps)
{
your function is a function that takes an integer x, another integer r, and a third integer steps. Indeed, it also returns an integer.
The algorithm you describe can be implemented in this way:
#include <stdio.h>
#include <math.h>
double heron(double x, double err)
{
double a = x, b = 1.0;
while (a - b > err) {
a = (a + b)/2.0; /* arithmetic mean */
b = x / a; /* approx to geometric mean */
}
return a; /* or b, depending if you want a value in excess or in defect */
}
int main()
{
printf("heron(2.0, 1.0E-10) = %.10f\n", heron(2.0, 1.0E-10));
printf("sqrt(2.0) = %.10f\n", sqrt(2.0));
}
and that will work.
Read about function parameter type definitions in one of the many references of the C programming languages, e.g. "The C programming language" from Brian Kernighan & Dennis Ritchie, for reference.
$ ./heron
heron(2.0, 1.0E-10) = 1.4142135624
sqrt(2.0) = 1.4142135624
$ _

C segfault using long integers

I don't understand why this code compiles and then segfaults:
#include <stdio.h>
#include <stdlib.h>
unsigned long int gcd(unsigned long int, unsigned long int);
unsigned long int lcm(unsigned long int, unsigned long int);
int main(int argc, char *argv[]) {
int i;
unsigned long int n = 1L;
for (i = 2; i < 21; i++) {
n = lcm(n, i);
}
printf("%ld\n", n);
return 0;
}
unsigned long int gcd(unsigned long int a, unsigned long int b) {
if (a == b) return a;
if (a > b) return gcd(a - b, b);
return gcd(a, b - a);
}
unsigned long int lcm(unsigned long int a, unsigned long int b) {
return abs(a * b) / gcd(a, b);
}
Are those unsigned longs even necessary? I also noted that if I change that 21 to a 18 it gives the correct result. The code is meant to find the LCM of all the numbers from 1 to 20.
Running it in gdb gives:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400643 in gcd (a=7536618, b=18) at p5.c:19
19 if (a > b) return gcd(a - b, b);
You're overflowing the stack. Which is a shame, because that should be easily optimized as tail recursion, full recursion is extremely overkill for this. Using the proper optimization levels in any modern compiler (cl, gcc, icc) should get rid of the segfault.
Luckily writing this iteratively is trivial as hell:
unsigned long gcd(unsigned long a, unsigned long b)
{
while(a != b)
if(a > b)
a -= b;
else
b -= a;
return a;
}
Due to how the stack and how they work, there's a limit on how deep function calls can be nested, depending on how much local state they keep.
For extremely imbalanced arguments, implementing gcd by repeated subtraction requires a lot of iterations, and so your recursion goes way to deep. You need to either change the implementation (e.g. make it iterative), or change the algorithm (e.g. compute remainders instead of differences).
You could increase the stack size, but that is wasteful of memory and the larger size will run eventually run out too with larger inputs.

Wrong result in C

I want to write a program that calculates expontiation using the Gauss' algorithm but if give input etc base=2,exp=50 i get as a result 0.0000.
#include<stdio.h>
float fastpower(int a,int b);
main()
{
int base,exp;
printf("Base:\n");
scanf("%d",&base);
printf("Exp:\n");
scanf("%d",&exp);
fastpower(base,exp);
system("pause");
}
float fastpower(int a,int b)
{
double result=1;
while (b>0)
{
if (b%2!=0)
result=result*a;
b=(b/2);
a=a*a;
}
printf("result is %lf\n",result);
}
Declare a as long (int64):
/*
compute a**b
*/
/* double fastpower(double a, int b) is even more better */
double fastpower(long a, int b) { /* double is more natural here: double result */
double result = 1.0;
while (b > 0) {
if (b % 2 != 0)
result *= a;
b /= 2;
a *= a; /* <- a is long to prevent overflow here */
}
/* You'd rather not output in functions */
printf("result is %lf\n", result);
return result; /* do not forget to return the result*/
}
But long could do overflow as well (e.g. 10**50); in this case use double for a

how to make negative numbers into positive

I am having the negative floating point number as:
a = -0.340515;
to convert this into positive number I used the abs() method as:
a = abs(a);
the result is a = 0.000000;
But I need the result as 0.340515.
Can anyone tell me how to do this.
abs() is for integers only. For floating point, use fabs() (or one of the fabs() line with the correct precision for whatever a actually is)
You have to use: abs() for int fabs() for double fabsf() for float Above function will also work but you can also try something like this.
if(a<0)
{
a=-a;
}
Use float fabsf (float n) for float values.
Use double fabs (double n) for double values.
Use long double fabsl(long double) for long double values.
Use abs(int) for int values.
Well, in mathematics to convert a negative number to a positive number you just need to multiple the negative number by -1;
Then your solution could be like this:
a = a * -1;
or shorter:
a *= -1;
a *= (-1);
problem solved. If there is a smaller solution for a problem, then why you guys going for a complex solution. Please direct people to use the base logic also because then only the people can train their programming logic.
floor a;
floor b;
a = -0.340515;
so what to do?
b = 65565 +a;
a = 65565 -b;
or
if(a < 0){
a = 65565-(65565+a);}
#include <iostream>
using namespace std;
int makePositiveSUM(int a,int b);
int main() {
int t;
cin>>t;
while(t--){
int x,y;
cin>>x>>y;
cout<<makePositiveSUM(x,y)<<endl;
}
return 0;
}
int makePositiveSUM(int a,int b){
if(a>b){
return a-b;
}
else {
return b-a;
}
}
enter code here
enter code here
enter code here
this is the only way i can think of doing it.
//positive to minus
int a = 5; // starting with 5 to become -5
int b = int a * 2; // b = 10
int c = a - b; // c = - 5;
std::cout << c << endl;
//outputs - 5
//minus to positive
int a = -5; starting with -5 to become 5
int b = a * 2;
// b = -10
int c = a + b
// c = 5
std::cout << c << endl;
//outputs 5
Function examples
int b = 0;
int c = 0;
int positiveToNegative (int a) {
int b = a * 2;
int c = a - b;
return c;
}
int negativeToPositive (int a) {
int b = a * 2;
int c = a + b;
return c;
}
Why do you want to use strange hard commands, when you can use:
if(a < 0)
a -= 2a;
The if statement obviously only applies when you aren't sure if the number will be positive or negative.
Otherwise you'll have to use this code:
a = abs(a) // a is an integer
a = fabs(a) // a is declared as a double
a = fabsf(a) // a is declared as a float (C++ 11 is able to use fabs(a) for floats instead of fabs)
To activate C++ 11 (if you are using Code::Blocks, you have to:
Open up Code::Blocks (recommended version: 13.12).
Go to Settings -> Compiler.
Make sure that the compiler you use is GNU GCC Compiler.
Click Compiler Settings, and inside the tab opened click Compiler Flags
Scroll down until you find: Have g++ follow the C++ 11 ISO C++ language standard [-std=c++11]. Check that and then hit OK button.
Restart Code::Blocks and then you are good to go!
After following these steps, you should be able to use fabs(a) for floats instead of fabsf(a), which was used only for C99 or less! (Even C++ 98 could allow you to use fabs instead of fabsf :P)

Resources