for loop multiple variable, second variable not updating - c++

I am trying to write two loops in one for loop so I looked up the syntax for multiple variables in the for loop
the problem is the second variable l isn't updating I don't know why
#include<iostream>
using namespace std;
int main ()
{
float vsum=0, lsum=0;
double nsum=0, msum=0;
float v=1, l=100000000;
for (v, l ; v<= 100000000, l >= 1 ; v++, l--)
{
vsum= vsum + 1/v;
nsum= nsum + 1/v;
lsum= lsum + 1/l;
msum= msum+ 1/l;
}
cout << " The float sum of all numbers 1 through 1/100000000 is " << vsum << endl;
cout << " The double sum of all numbers 1 through 1/100000000 is " << nsum << endl;
cout << "The float sum of all numbers 1/100000000 through 1/1 is " << lsum << endl;
cout << "The double sum of all numbers 1/100000000 through 1/1 is " << msum << endl;
cin >> vsum;
}

I guess your question is that after
float f = 100000000;
why does --f; leave f unchanged?
The answer is due to the granularity of float. The float does not have enough accuracy to store every possible integer. Clearly a 32-bit float cannot store as many integer values as a 32-bit int, for example.
The further away from 0 you get, the larger the gap gets between successive possible values of a float. On your system 100000000 - 1 is still larger than the next possible value of float below 100000000.
The rules of C++ are that when the result of the calculation is not representable exactly by a float, then it's implementation-defined whether the next-lowest value or the next-highest value is used. (So your compiler should actually document what happens here). In this case your system is using the next-highest value.
To get your intended results, make v and l be integral types, and do a float conversion in the actual calculation, e.g.
vsum += 1.f/v;
nsum += 1.0/v;

As dasblinkenlight mentions, you are only checking the second condition, but the second variable is updating just fine. Here is an abridged example that proves this.
#include<iostream>
using namespace std;
int main ()
{
float vsum=0, lsum=0;
double nsum=0, msum=0;
float v=1, l=10;
for (v, l ; v<= 10, l >= 1 ; v++, l--)
{
cout << v << " " << l << endl;
}
}
Output:
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1

Related

Why is the volume always calculated by zero?

I'm beginner in using functions, and I wrote this simple code. But I don't know why the volume is always calculated as zero.
#include <iostream>
using namespace std;
double area (double) ;
double volume (double) ;
int main () {
double radious ;
cout << "please enter the Radious \n" ;
cin >> radious ;
cout << "The area = " << area(radious) << "\n" ;
cin >> radious ;
cout << "The volume = " << volume(radious) << "\n" ;
cout << radious << "\n" ;
}
// defintion function of the area
double area (double R) {
return ( (4) * (3.14) * (R * R) ) ;
}
// defintion function of the volume
double volume (double R) {
return ( (3/4) * (3.14) * (R * R * R) ) ;
}
Your function volume will always return zero because 3 divided by 4 is 0 when interpreted as an integer. This is because casting any real value to integer will simply result in discarding decimal part. For example, 2.7 as int will be 2 not 3, there is no rounding, in a mathematical sense.
You can fix this in 2 ways:
A) reorder your equation so division will be the last operation you do, e.g. ((3.14*R*R*R*3)/4). Note that this is often necessary, when you want your result to be int, which is not the case here.
B) explicitly say that either (or both) 3 or 4 have to be treated as a real number (float/double) by adding .0, e.g. 3.0/4 or 3/4.0 or 3.0/4.0. This approach is better in your case since you expect double anyway.
For more information refer to Numeric conversions and this FAQ
The part 3/4 in your code performs an integer division. Integers cannot have floating points so usually the last part of integer is truncated, which leaves 0 in your case.
You can replace 3/4 with 3.0/4.0to make it work.
Good Luck!

I implemented my own square root function in c++ to get precision upto 9 points but it's not working

I want to get square root of a number upto 9 precision points so I did something like below but I am not getting correct precision. Here e is the precision which is greater than 10^9 then also ans is upto 5 precision points. What am I doing wrong here??
#include <iostream>
using namespace std;
long double squareRoot(long double n)
{
long double x = n;
long double y = 1;
long double e = 0.00000000000001;
while (x - y > e)
{
x = (x + y) / 2;
y = n / x;
}
cout << x << "\n";
return x;
}
int main()
{
int arr[] = {2,3,4,5,6};
int size = sizeof(arr)/sizeof(arr[0]);
long double ans = 0.0;
for(int i=0; i<size; i++)
{
ans += squareRoot(arr[i]);
}
cout << ans << "\n";
return 0;
}
The output is
1.41421
1.73205
2
2.23607
2.44949
9.83182
What should I do to get precision upto 9 points??
There are two places at which precision plays a role:
precision of the value itself
precision of the output stream
You can only get output in desired precision if both value and stream are precise enough.
In your case, the calculated value doesn't seem to be a problem, however, default stream precision is only five digits, i. e. no matter how precise your double value actually is, the stream will stop after five digits, rounding the last one appropriately. So you'll need to increase stream precision up to the desired nine digits:
std::cout << std::setprecision(9);
// or alternatively:
std::cout.precision(9);
Precision is kept until a new one is set, in contrast to e. g. std::setw, which only applies for next value.
try this
cout << setprecision(10) << x << "\n";
cout << setprecision(10) << ans << "\n";

Weird mistake in taking the sums of elements in alglib::real_1d_array

OK this time I have a really weird mistake that does not always appear. Here is the function that actually contains problems. All it does is literally summing elements of a vector. It works in most cases but in a few cases it tend to become highly problematic.
int sumvec(vect v) {
int i = 0;
int sum = 0;
int l = v.length();
std::cout << "Sum of vector " << v.tostring(3) << std::endl;
for (; i < l; i++) {
sum += v[i];
std::cout << v[i] << " " << sum << " ";
};
std::cout << std::endl;
return sum;
}
Here vect is defined using typedef alglib::real_1d_array vect;. OK so what do I get? Huh..
Sum of vector [1.000,1.000,0.000,1.000,1.000,1.000]
1 0 1 0 0 0 1 0 1 0 1 1
What?!!!!!
As your sum variable is an integer you may not get the expected results when summing elements in your vector which are not integers.
If your elements have the value of 0.999999999 rather than 1.00000 then printing them could be rounded to 1.00000 but when you add them to an integer the value will be truncated to 0.
Judging by the provided output all of your values are less than 1 apart from the last one which is greater or equal to 1.
There are 2 possible solutions:
Change the type of sum to be float or double.
Change your calculation to: sum += static_cast<int>(round( v[i] ));
Note that your compiler was probably warning about the truncation of a double to an integer. Pay attention to compiler warnings, they often indicate a bug.
As commented use a double to store the sum if you are working with floating point integers. using an integer will cause the variable to be implicitely casted to an int which just cuts of the mantissa:
0.9999998 -> 0
Depending on cout::precision, 0.99999 would be printed as 1.0000(rounded) or without std::fixed just as 1 what propably happens in your example.
double a = 0.999;
std::cout.precision(2);
std::cout << a << std::endl; /* This prints 1 */
std::cout << std::fixed;
std::cout << a << endl; /* This prints 1.00 */

Computing fibonacci like function in sublinear time

So, here is the problem:
Given a number n I need to calculate the amount of calls it would need to calculate the fibonacci of that number recursively and output only the last digit in a given base as a decimal. The input comes as 2 numbers being the first the number n and the second the base that the output should be in. For the output should be the case number, the first input, the second input and the result of the calculation. The program should exit when the first entry is equal to the second entry that equals 0. For example:
Input:
0 100
1 100
2 100
3 100
10 10
3467 9350
0 0
Output:
Case 1: 0 100 1
Case 2: 1 100 1
Case 3: 2 100 3
Case 4: 3 100 5
Case 5: 10 10 7
Case 6: 3467 9350 7631
I have arrived on the following formula when trying to solve this. Being c(n) the last digit of the number of calls it would take in a base b, we have that:
c(n) = (c(n-1) + c(n-2) + 1) mod b
The problem is that n can be any value from 0 to 2^63 - 1 so I really need the code to be efficient. I have tried doing in a iterative way or using dynamic programming but, although it give me the right output, it doesn't give me in a short enough time. Here is my code:
Iterative
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<unsigned long long int> v;
unsigned long long int x,y,co=0;
cin >> x >> y;
while(x||y){
co++;
v.push_back(1);
v.push_back(1);
for(int i=2;i<=x;i++) v.push_back((v[i-1]+v[i-2]+1)%y);
cout << "Case " << co << ": " << x << " " << y << " " << v[x] << endl;
cin >> x >> y;
v.clear();
}
return 0;
}
Dynamic programming
#include <iostream>
#include <vector>
using namespace std;
vector<unsigned long long int> v;
unsigned long long c(int x, int y){
if(v.size()-1 < x) v.push_back((c(x-1,y) + c(x-2,y) + )%y);
return v[x];
}
int main(){
int x,y,co=0;
cin >> x >> y;
while(x||y){
co++;
v.push_back(1);
v.push_back(1);
cout << "Case " << co << ": " << x << " " << y << " " << c(x,y) << endl;
cin >> x >> y;
v.clear();
}
return 0;
}
x and y are respectively n and b, v holds the values for c(n)
Every c in the sequence is less than b. So there are b possibilities for the value of a c. So a pair of consecutive elements [ck, ck+1] can have b2 possible values. So if you start at the beginning and calculate c1, c2, c3... you will have to calculate at most b2 of them before the sequence begins to repeat; you will come to a [ck, ck+1] that is equal to an earlier [cj, cj+1].
Then you know the length of the cycle, call it S, and you know that cn = c((n-j)mod S)+j for all n > j. That should cut your work down quite a lot.

While loop logic clarification + harmonic series

This is my code for finding the sum of a harmonic series of 1/n. I want it to stop when the sum is greater than or equal to 15, but the code cannot run. Can anyone let me know what I'm doing wrong? It seems to follow the correct while loop structure. Thanks!
#include <iostream>
using namespace std;
int main ()
{
int divisor = 1;
int sum = 1;
while ((sum <= 15) && (divisor >=1))
{
sum = sum + (1/divisor);
divisor++;
}
cout << "You need " << divisor << " terms to get a sum <= 15" << endl;
return 0;
}
Your loop is actually running. However, your sum variable is of type int, and so is divisor.
1 (an int) / divisor (also an int) will return 1 or 0. This is because you are doing integer division. 1/1 == 1. However, 1/2 == 0, 1/3 == 0, etc... To solve this, cast divisor to double:
(1 / (double)divisor)
So that solves the issue of that segment returning only 1 or 0. However, you will still gain a sum of 1 as sum is of type int. Attempting to assign a double to an int variable will result in a truncation, or floor rounding. Sum will add the first 1, but it will remain 1 indefinitely after that. In order to solve this, change the type of sum to double.
Your assignment of sum = 1; is a logical error. Your result will be 1 higher than it should be. Your output statement is also mistaken... It should be...
cout << "You need " << divisor << " terms to get a sum > 15" << endl;
In addition, the condition of divisor >= 1 is needless... It is always greater than or equal to one because you assign it as 1 and are incrementing... If you do want a sum that is >= 15, change the while condition to...
while (sum < 15)
Your code should look like this...
#include <iostream>
using namespace std;
int main()
{
int divisor = 1;
double sum = 0; //Changed the type to double and assigned 0 rather than 1
while (sum <= 15) //While condition shortened...
{
sum = sum + (1 / (double)divisor); //Added type cast to divisor
divisor++;
}
//cout statement adjusted...
cout << "You need " << divisor << " terms to get a sum > 15" << endl;
return 0;
}