I've written a naive (only accepts integer exponents) power function for complex numbers (a home made class) using a simple for loop that multiplies the result for the original number n times:
C pow(C c, int e) {
C res = 1;
for (int i = 0; i==abs(e); ++i) res=res*c;
return e > 0 ? res : static_cast<C>(1/res);
}
When I try to execute this, e.g.
C c(1,2);
cout << pow(c,3) << endl;
I always get 1, because the for loop doesn't execute (I checked).
Here's the full code:
#include <cmath>
#include <stdexcept>
#include <iostream>
using namespace std;
struct C {
// a + bi in C forall a, b in R
double a;
double b;
C() = default;
C(double f, double i=0): a(f), b(i) {}
C operator+(C c) {return C(a+c.a,b+c.b);}
C operator-(C c) {return C(a-c.a,b-c.b);}
C operator*(C c) {return C(a*c.a-b*c.b,a*c.b+c.a*b);}
C operator/(C c) {return C((a*c.a+b*c.b)/(pow(c.a,2)+pow(c.b,2)),(b*c.a - a*c.b)/(pow(c.a,2)+pow(c.b,2)));}
operator double(){ if(b == 0)
return double(a);
else
throw invalid_argument(
"can't convert a complex number with an imaginary part to a double");}
};
C pow(C c, int e) {
C res = 1;
for (int i = 0; i==abs(e); ++i) {
res=res*c;
// check wether the loop executes
cout << res << endl;}
return e > 0 ? res : static_cast<C>(1/res);
}
ostream &operator<<(ostream &o, C c) { return c.b ? cout << c.a << " + " << c.b << "i " : cout << c.a;}
int main() {
C c(1,2), d(-1,3), a;
cout << c << "^3 = " << pow(c,3) << endl;}
What you wrote will read as follows:
for (int i = 0; i == abs(e); ++i)
initialize i with 0 and while i is equal to the absolute value of e (i.e. 3 at the beginning of the function call), do something
It should rather be
for (int i = 0; i < abs(e); ++i)
Tip: the code will throw at the first iteration due to the double conversion operator (and caused by a*c.b + c.a*b), but this is another issue: fix your complex (i.e. with imaginary part) printing function or implement a pretty printing method or such.
you should be using i != abs(e) or i < abs(e) as for loop condition. Currently you are using i == abs(e) which will fail in first try because:
i = 0
abs(e) = 3
so 0 == 3 is false and hence for loop will not execute.
Related
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
double* cal1(double* all1)
{
int t,count=0;
ifstream srcFile("in.txt", ios::in);
if (!srcFile)
{
cout << "error opening source file." << endl;
return 0;
}
char x;
while (srcFile >> x)
{
t = x - 'a' ;
count++;
if (t >= 0 && t <= 25)
all1[t]++;
else
all1[26]++;
}
all1[27] =count ;
srcFile.close();
/* for (t = 0; t <= 26; t++)
{
cout << all1[t] / all1[27]<<endl;
}
cout << all1[27] << endl;*/
return all1;
}
double finalcal1(double* all)
{
int t;
double p,cal1=0;
for (t = 0; t <= 26; t++)
{
p = (all[t] / all[27]);
all[t] = p * log(p);
}
for (t = 0; t <= 26; t++)
{
cal1 -= all[t];
}
return cal1;
}
int main()
{
double *all =new double[28]; //1
double t;
all = cal1(all);
t = finalcal1(all);
cout << t << endl;
delete[] all;
return 0;
}
enter code here
instead of receiving a number from the result, I just got a “-nan.(ind)” which is not even a number. Besides, when I change the number from mark 1 to *all =new double[27] which is what it supposed to be, there would be error or bugs showing up.
double *all =new double[28];
You probably want to initialise all these values to zero to start with since, otherwise, they'll have arbitrary values.
And, if those arbitrary values consist of any NaN items, that will propagate when you add things to them, or divide by some count.
Something like this will do the trick:
double *all = new double[28]();
You may also want to consider the possibility that log(x) is not actually defined for all values of x (such as zero or negative values) - that may be another way in which you could get a NaN.
this is my first time posting a question. I was hoping to get some help on a very old computer science assignment that I never got around to finishing. I'm no longer taking the class, just want to see how to solve this.
Read in an integer (any valid 64-bit
integer = long long type) and output the same number but with commas inserted.
If the user entered -1234567890, your program should output -1,234,567,890. Commas
should appear after every three significant digits (provided more digits remain) starting
from the decimal point and working left toward more significant digits. If the number
entered does not require commas, do not add any. For example, if the input is 234 you
should output 234. The input 0 should produce output 0. Note in the example above
that the number can be positive or negative. Your output must maintain the case of the
input.
I'm relatively new to programming, and this was all I could come up with:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long n;
cout << "Enter an integer:" << endl;
cin >> n;
int ones = n % 10;
int tens = n / 10 % 10;
int hund = n / 100 % 10;
int thous = n / 1000 % 10;
int tthous = n / 10000 % 10;
cout << tthous << thous << "," << hund << tens << ones << endl;
return 0;
}
The original assignment prohibited the use of strings, arrays, and vectors, so please refrain from giving suggestions/solutions that involve these.
I'm aware that some sort of for-loop would probably be required to properly insert the commas in the necessary places, but I just do not know how to go about implementing this.
Thank you in advance to anyone who offers their help!
Just to give you an idea how to solve this, I've maiden a simple implementation. Just keep in mind that is just a simple example:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long n = -1234567890;
if ( n < 0 )
cout << '-';
n = abs(n);
for (long long i = 1000000000000; i > 0; i /= 1000) {
if ( n / i <= 0 ) continue;
cout << n / i ;
n = n - ( n / i) * i;
if ( n > 0 )
cout << ',';
}
return 0;
}
http://coliru.stacked-crooked.com/a/150f75db89c46e99
The easy solution would be to use ios::imbue to set a locale that would do all the work for you:
std::cout.imbue(std::locale(""));
std::cout << n << std::endl;
However, if the restraints don't allow for strings or vectors I doubt that this would be a valid solution. Instead you could use recursion:
void print(long long n, int counter) {
if (n > 0) {
print(n / 10, ++counter);
if (counter % 3 == 0) {
std::cout << ",";
}
std::cout << n%10;
}
}
void print(long long n) {
if (n < 0) {
std::cout << "-";
n *= -1;
}
print(n, 0);
}
And then in the main simply call print(n);
A small template class comma_sep may be a solution, the usage may be as simple as:
cout << comma_sep<long long>(7497592752850).sep() << endl;
Which outputs:
7,497,592,752,850
Picked from here:
https://github.com/arloan/libimsux/blob/main/comma_sep.hxx
template <class I = int, int maxdigits = 32>
class comma_sep
char buff[maxdigits + maxdigits / 3 + 2];
char * p;
I i;
char sc;
public:
comma_sep(I i, char c = ',') : p(buff), i(i), sc(c) {
if (i < 0) {
buff[0] = '-';
*++p = '\0';
}
}
const char * sep() {
return _sep(std::abs(i));
}
private:
const char * _sep(I i) {
I r = i % 1000;
I n = i / 1000;
if (n > 0) {
_sep(n);
p += sprintf(p, "%c%03d", sc, (int)r);
*p = '\0';
} else {
p += sprintf(p, "%d", (int)r);
*p = '\0';
}
return buff;
}
};
The above class handles only integeral numbers, float/double numbers need to use a partial specialized version:
template<int maxd>
class comma_sep<double, maxd> {
comma_sep<int64_t, maxd> _cs;
char fs[64];
double f;
public:
const int max_frac = 12;
comma_sep(double d, char c = ',') : _cs((int64_t)d, c) {
double np;
f = std::abs(modf(d, &np));
}
const char * sep(int frac = 3) {
if (frac < 1 || frac > max_frac) {
throw std::invalid_argument("factional part too too long or invalid");
}
auto p = _cs.sep();
strcpy(fs, p);
char fmt[8], tmp[max_frac+3];
sprintf(fmt, "%%.%dlf", frac);
sprintf(tmp, fmt, f);
return strcat(fs, tmp + 1);
}
};
The two above classes can be improved by adding type-traits like std::is_integral and/or std::is_floating_point, though.
Here is the C++ program i wrote to solve the above series:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int factorial(int a)
{
if (a > 1)
return a * factorial(a - 1);
else
return 1;
}
float series(float x, int n, float b)
{
if (abs(pow(x, n) / factorial(n)) < pow(10, -6) || abs(pow(x, n) / factorial(n)) == pow(10, -6)) { return b; }
else return b = (pow(x, n) / factorial(n)) + series(x, n + 1, b);
}
int main()
{
float x;
cout << "Enter x: "<<endl;
cin >> x;
cout << "E^x = " << series(x,0,0);
system("pause");
return 0;
}
It works fine when abs(x) < 2 but when abs(x) >= 2 this error appears:
Unhandled exception at 0x00F02539 in 33b.exe: 0xC00000FD: Stack
overflow (parameters: 0x00000001, 0x00F22FF8). occurred
I want to know why does this happen and how can i fix it?
Your problem is too deep recursion. Consider loop instead.
float series(float x)
{
const float epsilon = 1e-6f;
double error = 1;
double res = 1.f;
int iter = 1;
while (abs(error) > epsilon) {
error *= (x / iter++);
res += error;
cout << error << endl;
}
return res;
}
int main()
{
cout << "E^x = " << series(3);
system("pause");
return 0;
}
To be clearer about what happens:
When you call a function inside another function, the context of the parent function is saved to make room for the new context. When you make millions of inception, the memory stack in charge to save these context is full and overflows.
This is a Stack Overflow.
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
int factorial[200];
int Factorial(int a)
{ if(a>0){
factorial[a]=a * factorial[a-1];
return factorial[a];
}
else
factorial[a]=1;
return 1;
}
double series(double x, int n, double b)
{ double temp=(abs(pow(x, n)) / Factorial(n));
if (temp <= 0.000001) { return b; }
else return (temp + series(x, n + 1, b));
}
int main()
{
float x;
cout << "Enter x: "<<endl;
cin >> x;
cout << "E^x = " << series(x,0,0);
system("pause");
return 0;
}
umm this solution is working. all i did was i took your code removed abs(pow(x, n) / factorial(n)) wherever its repeating and intialised to a new variable temp. then instead of < || == u can directly put <=. and rather than invoking a a function to calculate .000001 every time you could just give that value to reduce time further. however i believe that the reason why the code may not have worked is too much recursion. so for factorials i used dynamic programming to reduce its complexity. the above code is working perfectly fine.
I need to count how many cubes of values between a and b (2 and 9 in this example) end with numbers between 2 and 5. Everything has to be done with recursion.
The output of this code is
part c = recc = 4
32767
0
It does not make sense to me. It calculates the value of n correctly, but then once asked to return it, returns either 0 or 32767, as if it was not defined.
Can anyone pinpoint the issue?
#include <iostream>
#include <string>
using namespace std;
void partb(int a, int b){
if(a<=b){
int p = (a*a*a)%10;
else if(p>=2 && p<=5){
cout<<a*a*a<<" ";
}
partb(a+1, b);
}
}
int recc(int n, int a, int b){
int p = (a*a*a)%10;
if(a>b){
cout<<"recc = " << n << endl;
return n;
}
else if(a<=b){
if(p>=2 && p<=5){
n++;
}
recc(n, a+1, b);
}
}
int partc(int a, int b){
int n = recc(0, a, b);
cout<<endl<< "part c = " << recc(0, a, b) << endl;
return n;
}
int main(){
int n=partc(2,9);
cout << n << endl;
return 0;
}
Not all control paths in your function return a value, so you were getting undefined behaviour when using the return value.
Now, this wasn't helped by the fact that the function itself is needlessly complicated. Let's rewrite it to use common practice for recursion:
int recc(int a, int b)
{
if (a > b) return 0;
int p = (a*a*a)%10;
int n = (p>=2 && p<=5) ? 1 : 0;
return n + recc(a+1, b);
}
Now your function is simpler. The recursion termination condition is right at the top. The function then decides whether a will contribute 1 or 0 to the count. And finally you return that value plus the count for a smaller range.
Notice how return n + recc(a+1, b); has broken the problem into a simple local solution combined with the recursive result of a reduced scope.
The invocation becomes simpler too, because you no longer have to pass in a redundant argument:
int partc(int a, int b)
{
int n = recc(a, b);
cout << endl << "part c = " << n << endl;
return n;
}
I'm having issues with my adaptive trapezoidal rule algorithm in C++ -- basically, regardless of the tolerance specified, I get the same exact approximation. The recursion is supposed to stop very early for large tolerances (since abs(coarse-fine) is going to be smaller than 3.0*large tolerance and minLevel of recursion is about 5).
However, what this function does is run the maximum number of times regardless of choice of tolerance. Where did I mess up?
EDIT: Perhaps there are issues in my helper functions?
double trap_rule(double a, double b, double (*f)(double),double tolerance, int count)
{
double coarse = coarse_helper(a,b, f); //getting the coarse and fine approximations from the helper functions
double fine = fine_helper(a,b,f);
if ((abs(coarse - fine) <= 3.0*tolerance) && (count >= minLevel))
//return fine if |c-f| <3*tol, (fine is "good") and if count above
//required minimum level
{
return fine;
}
else if (count >= maxLevel)
//maxLevel is the maximum number of recursion we can go through
{
return fine;
}
else
{
//if none of these conditions are satisfied, split [a,b] into [a,c] and [c,b] performing trap_rule
//on these intervals -- using recursion to adaptively approach a tolerable |coarse-fine| level
//here, (a+b)/2 = c
++count;
return (trap_rule(a, (a+b)/2.0, f, tolerance/2.0, count) + trap_rule((a+b)/2.0, b, f, tolerance/2.0, count));
}
}
EDIT: Helper and test functions:
//test function
double function_1(double a)
{
return pow(a,2);
}
//"true" integral for comparison and tolerances
//helper functions
double coarse_helper(double a, double b, double (*f)(double))
{
return 0.5*(b - a)*(f(a) + f(b)); //by definition of coarse approx
}
double fine_helper(double a, double b, double (*f)(double))
{
double c = (a+b)/2.0;
return 0.25*(b - a)*(f(a) + 2*f(c) + f(b)); //by definition of fine approx
}
double helper(double a, double b, double (*f)(double x), double tol)
{
return trap_rule(a, b, f, tol, 1);
}
And here's what's in main():
std::cout << "First we approximate the integral of f(x) = x^2 on [0,2]" << std::endl;
std::cout << "Enter a: ";
std::cin >> a;
std::cout << "Enter b: ";
std::cin >> b;
true_value1 = analytic_first(a,b);
for (int i = 0; i<=8; i++)
{
result1 [i] = helper(a, b, function_1, tolerance[i]);
error1 [i] = fabs(true_value1 - result1 [i]);
}
std::cout << "(Approximate integral of x^2, tolerance, error )" << std::endl;
for (int i = 0; i<=8; i++)
{
std::cout << "(" << result1 [i] << "," << tolerance[i] << "," << error1[i] << ")" << std::endl;
}
I find that exactly the opposite of what you suggest is happening --- the algorithm is terminating after only minLevel steps --- and the reason is due to your usage of abs, rather than fabs in the tolerance test. The abs is converting its argument to an int and thus any error less than 1 is getting rounded to zero.
With the abs in place I get this output from a very similar program:
(0.333496,0.001,0.00016276)
(0.333496,0.0001,0.00016276)
(0.333496,1e-05,0.00016276)
(0.333496,1e-06,0.00016276)
(0.333496,1e-07,0.00016276)
(0.333496,1e-08,0.00016276)
(0.333496,1e-09,0.00016276)
(0.333496,1e-10,0.00016276)
(0.333496,1e-11,0.00016276)
Replacing with fabs I get this:
(0.333496,0.001,0.00016276)
(0.333374,0.0001,4.06901e-05)
(0.333336,1e-05,2.54313e-06)
(0.333334,1e-06,6.35783e-07)
(0.333333,1e-07,3.97364e-08)
(0.333333,1e-08,9.93411e-09)
(0.333333,1e-09,6.20882e-10)
(0.333333,1e-10,3.88051e-11)
(0.333333,1e-11,9.7013e-12)