Having trouble with decimal float in struct array [duplicate] - c++

This question already has answers here:
Why does division result in zero instead of a decimal?
(5 answers)
Closed 1 year ago.
I am having some trouble and I cant really even figure out what is wrong, so I needed some help.
I need to take a percentage of a number that one of the structs in my array has, for each one.
my struct looks like
struct person{
int number;
string name;
float share;
}
So I use a for loop to get the total of number, no problem, all comes out good. But when I try to get what percent of the total I always get a zero.
for (int i=0; i<numberOfPersons;i++){
people[i].share = 100 * ((people[i].number)/totalNumber);
}
I don't understand what is going wrong here but people[i].share always comes out as 0.00 when I cout it.
literally all I do after this is cout it and I get the correct values from number and totalNumber. So I'm like really confused.
If I flip the division problem around I get answers(not the right ones obviously), so I know that there is data in the fields when the for loop runs. But where is it going when I run the equation the way I need to run it?
I tried initializing it and leaving uninitialized, swapping the pointers for ints made inside the loop, and more and I always get the same result.
Please help me understand.

I presume your type of totalnumber is int and person.number is int as well.
For operation between ints, the return value is still int
Expanding people[i].share = 100 * ((people[i].number)/totalNumber);
It would be something like people[i].share = 100 * ( 1/10 );
=> people[i].share = 100 * ( 0 );
=> people[i].share = 0;
So you will get 0 as a result;
To prevent it, cast one of int to float.
people[i].share = 100 * ((static_cast<float>(people[i].number))/totalNumber);

Related

Collecting remainders while converting a number to ternary base ( C++ )

I am trying to write a program in C++. It's a much longer program, but I need help regarding just one of the functions in it.
Basically, this function should get a number, and then return that same number but in ternary base. Now, my idea is to basically divide that number by 3 and collect remainders ( if my number is "n", I'd use n%3) and then I would just divide that number with 3 ( n/3 ) and go again until that number "n" by repeated division becomes 0.
This should work and convert the number to ternary base, but my problem is the fact that I do not know how to collect these remainders. This is probably a stupid question, but I am still a begginer in programming.
Basically, if I make a while loop , something like this :
while(n>0)
{
int digitofternary=n%3;
n/=3;
}
In every iteration of while loop, digitofternary is just going to change. How can I adjust this loop so digits get remembered/collected and I can return a new normal ternary base number from function?
Sorry if this sounded confusing, hope it didn't ( I am not a native english speaker ).
int sample_fn (int n)
{
std::string str_ret;
while(n>0)
{
int digitofternary=n%3;
n/=3;
std::string str= std::to_string(digitofternary);
str_ret.append(str);
}
return std::stoi(str_ret);
}

Multiply numbers which are divisible by 3 and less than 10 with a while loop in c++?

In C++, I should write a program where the app detects which numbers are divisible by 3 from 1 till 10 and then multiply all of them and print the result. That means that I should multiply 3,6,9 and print only the result, which is 162, but I should do it by using a "While" loop, not just multiplying the 3 numbers with each other. How should I write the code of this? I attached my attempt to code the problem below. Thanks
#include <iostream>
using namespace std;
int main() {
int x, r;
int l;
x = 1;
r = 0;
while (x < 10 && x%3==0) {
r = (3 * x) + 3;
cout << r;
}
cin >> l;
}
Firstly your checking the condition x%3 == 0 brings you out of your while - loop right in the first iteration where x is 1. You need to check the condition inside the loop.
Since you wish to store your answer in variable r you must initialize it to 1 since the product of anything with 0 would give you 0.
Another important thing is you need to increment the value of x at each iteration i.e. to check if each number in the range of 1 to 10 is divisible by 3 or not .
int main()
{
int x, r;
int l;
x = 1;
r = 1;
while (x < 10)
{
if(x%3 == 0)
r = r*x ;
x = x + 1; //incrementing the value of x
}
cout<<r;
}
Lastly I have no idea why you have written the last cin>>l statement . Omit it if not required.
Ok so here are a few hints that hopefully help you solving this:
Your approach with two variables (x and r) outside the loop is a good starting point for this.
Like I wrote in the comments you should use *= instead of your formula (I still don't understand how it is related to the problem)
Don't check if x is dividable by 3 inside the while-check because it would lead to an too early breaking of the loop
You can delete your l variable because it has no affect at the moment ;)
Your output should also happen outside the loop, else it is done everytime the loop runs (in your case this would be 10 times)
I hope I can help ;)
EDIT: Forget about No.4. I didn't saw your comment about the non-closing console.
int main()
{
int result = 1; // "result" is better than "r"
for (int x=1; x < 10; ++x)
{
if (x%3 == 0)
result = result * x;
}
cout << result;
}
or the loop in short with some additional knowledge:
for (int x=3; x < 10; x += 3) // i know that 3 is dividable
result *= x;
or, as it is c++, and for learning purposes, you could do:
vector<int> values; // a container holding integers that will get the multiples of 3
for (int x=1; x < 10; ++x) // as usual
if ( ! x%3 ) // same as x%3 == 0
values.push_back(x); // put the newly found number in the container
// now use a function that multiplies all numbers of the container (1 is start value)
result = std::accumulate(values.begin(), values.end(), 1, multiplies<int>());
// so much fun, also get the sum (0 is the start value, no function needed as add is standard)
int sum = std::accumulate(values.begin(), values.end(), 0);
It's important to remember the difference between = and ==. = sets something to a value while == compares something to a value. You're on the right track with incrementing x and using x as a condition to check your range of numbers. When writing code I usually try and write a "pseudocode" in English to organize my steps and get my logic down. It's also wise to consider using variables that tell you what they are as opposed to just random letters. Imagine if you were coding a game and you just had letters as variables; it would be impossible to remember what is what. When you are first learning to code this really helps a lot. So with that in mind:
/*
- While x is less than 10
- check value to see if it's mod 3
- if it's mod 3 add it to a sum
- if not's mod 3 bump a counter
- After my condition is met
- print to screen pause screen
*/
Now if we flesh out that pseudocode a little more we'll get a skeletal structure.
int main()
{
int x=1//value we'll use as a counter
int sum=0//value we'll use as a sum to print out at the end
while(x<10)//condition we'll check against
{
if (x mod 3 is zero)
{
sum=x*1;
increment x
}
else
{
increment x
}
}
//screen output the sum the sum
//system pause or cin.get() use whatever your teacher gave you.
I've given you a lot to work with here you should be able to figure out what you need from this. Computer Science and programming is hard and will require a lot of work. It's important to develop good coding habits and form now as it will help you in the future. Coding is a skill like welding; the more you do it the better you'll get. I often refer to it as the "Blue Collar Science" because it's really a skillset and not just raw knowledge. It's not like studying history or Biology (minus Biology labs) because those require you to learn things and loosely apply them whereas programming requires you to actually build something. It's like welding or plumbing in my opinion.
Additionally when you come to sites like these try and read up how things should be posted and try and seek the "logic" behind the answer and come up with it on your own as opposed to asking for the answer. People will be more inclined to help you if they think you're working for something instead of asking for a handout (not saying you are, just some advice). Additionally take the attitude these guys give you with a grain of salt, Computer Scientists aren't known to be the worlds most personable people. =) Good luck.

Finding the square of a number without multiplication [duplicate]

This question already has answers here:
Making a square() function without x*x in C++
(7 answers)
Closed 4 years ago.
I'm a beginner in programming and trying to learn C++ by the book Programming principles and practice using C++. In some parts of the book there are little exercises that you can try to do, one of this exercises is about calculating the square of a number, here is what my book says :
Implement square() without using the multiply operator, that is, do the x * x by repetead addition (start a variable result to 0 and add x to it x times).
I've already found a solution for this program but my first tentative was something like this :
#include <iostream>
int main()
{
int a = 0;
std::cout << "Enter an integer value : ";
std::cin >> a;
while (a < a * a)
{
a += a;
std::cout << a << "\n";
}
}
I know this code is wrong but I can't understand the output of the progam, if I enter 5 the program prints 10 20 30 40 50 until 8000, why the for loop doesn't stop when a is greater than its square ? I'm just curious to undersant why
Using multiplication when trying to avoid multiplication seems broken. What about this:
int r = 0;
for (int n = 0; n < a; ++n) {
r += a;
}
why the for loop doesn't stop when a is greater than its square ?
Because it never is. If you compare the graph of y=x^2 against the graph of y=x, you will see that the only time y=x is above, is when 0 < x < 1. That's never the case for integers1. Now, since we're talking about computers with limited storage here, there is a thing called overflow, which will cause a very large number to become a very small number. However, signed integer overflow is undefined behavior in C++. So once your loop gets to the point where overflow would happen, you cannot rely on the results.
1. Note that your loop is not set to stop just when a is greater than its square, but when it is greater than or equal to its square. So, your loop will actually stop if a is 0 or 1.

SPOJ SCUBADIV - Recursive DP Approach [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have been trying to solve http://www.spoj.com/problems/SCUBADIV/ question at SPOJ. I have come up with a recursive DP solution.
I am using knapsack approach with a 3 dimensional array to store the number of cylinders, required oxygen weight, and nitrogen weight. At each recursive step I'm checking for the amount of oxygen and nitrogen yet to be filled. If it is negative, it's as good as zero.
#include<bits/stdc++.h>
using namespace std;
#define inf 99999999
int n;
vector<int> o;
vector<int> ni;
vector<int> w;
int ow;
int nw;
int knapsack(int n,int ow,int nw); // n - number of cylinders,ow-wt. of oxygen
// nw-wt. of nitogen.
int main(){
int t;
scanf("%d",&t);
while(t--){
int i;
scanf("%d %d",&ow,&nw);
scanf("%d",&n);
o.resize(n);
ni.resize(n);
w.resize(n);
for(i=0;i<n;i++)
scanf("%d%d%d",&o[i],&ni[i],&w[i]); // o[i] storing wt. of oxygen cylinders
int res = knapsack(n,ow,nw); //ni[i] storing wt. of nitrogen cylinders
printf("%d",res);
}
return 0;
}
int knapsack(int n,int ow,int nw){
int dp[n+1][ow+1][nw+1];
memset(dp,inf,sizeof (dp)); //setting value of array to inf to get minimum weight
int i;
for(i=0;i<n;i++)
dp[i][0][0]=0;
if(dp[n][ow][nw]!= inf)
return dp[n][ow][nw];
else if (ow - o[n-1]>=0 && nw - ni[n-1]>=0)
return dp[n][ow][nw]= min(knapsack(n-1,ow,nw),w[n-1]+knapsack(n-1,ow-o[n-1],nw-ni[n-1]));
else if(ow -o[n-1]<0 && nw - ni[n-1] >=0)
return dp[n][ow][nw]=min(knapsack(n-1,0,nw),w[n-1]+knapsack(n-1,0,nw-ni[n-1]));
else if(ow-o[n-1]>=0 && nw-ni[n-1]<0)
return dp[n][ow][nw]=min(knapsack(n-1,ow,0),w[n-1]+knapsack(n-1,ow-o[n-1],0));
else if(ow-o[n-1]<0 && nw-ni[n-1]<0)
return dp[n][ow][nw]= knapsack(n-1,0,0);
}
This code is not giving the desired result (it's giving -1). Is the approach correct ?
There is a problem with this code:
int dp[n+1][ow+1][nw+1];
memset(dp,inf,sizeof (dp));
The memset() function sets a byte pattern, not a value. Since inf is a larger-than-a-byte value, it is essentially doing inf % 256 and initializing all the bytes in dp[][][] to that value. This is further complicated by dp[][][] being of base type int, so 4 bytes set to the same byte value is something unexpected.
In the case of your value for inf, of 99999999, the byte value will be 0xff, and so all the ints in dp[][][] will be set to -1.
I don't know if this is expected, but it looks like it could be a mistake.
Let M(x, O, N) be the minimum weight of cylinders that will provide O liters of oxygen and N liters of nitrogen by choosing from only cylinders 1 to x. Let O(x), N(x), and W(x) be the amount of oxygen and nitrogen available in the x'th cylinder and the cylinder's weight respectively. Then either we choose to use the x'th cylinder or we don't:
M(x, O, N) = min( W(x) + M(x - 1, O - O(x), N - N(x)), M(x - 1, O, N) )
The base case occurs when we have no cylinders at all.
M(0, O, N) = 0 if O <= 0 and N <= 0, infinity otherwise
I won't be reading your unformatted, cryptically written code to figure out whether it implements this correctly. I will say memset can only be used to set bytes to a given value. Your call is not doing what you think. Additionally, your recursive procedure returns junk if execution reaches the end of the if chain.
Work a small example by hand. Run your code either in a debugger or with printfs inserted to show what's going on. Figure out where its actual execution diverges from your hand calculation.
Yes, it is possible to solve this problem with a recursive approach, but this is not how to do it. There are multiple problems with the code, and 'obviously' it will return -1. The question is I shall try to answer is: tell me some of the things wrong with this code.
Variable names like dp obscure the meaning of the code. Give them meaningful names!
Don't resize a vector and read into a pointer. Read values and push them onto the vector.
Print out the data to ensure you read it right.
The memset function fills with bytes, in this case -1. Use a loop to initialise ints.
The first if statement can only ever return 0 or -1 (or inf once you fix the init). As it is the other code will not be executed.
Assigning a value into dp is of no effect, since it is in automatic storage (on the stack).
I don't understand the chain of if statements. Explain them.
There is no else so the function can fall off the end.
Best to rewrite, debug, and if it still doesn't work come back with something we can read.

How do I convert this function into a loop?

I have an array of letters of an unknown number of elements which contains lower case letters. I have written a function for converting a lower case number to its ASCII value
int returnVal (char x)
{
return (int) x;
}
I am trying to combine all of these values into one number. Subtracting 87 from each of these means that the value is always a 2 digit number. I am able to combine an array made up if two elements by:
returnVal (foo[0]) - 87) + returnVal (foo[1] - 87) * 100
an array made up of three elements by
returnVal (foo[0]) - 87) + returnVal (foo[1] -87) * 100 + returnVal (foo[2] - 87) * 100 * 100
I am multiplying each element by 100^its position in the array and summing them. This means that [a,b,c] would become 121110 (yes, the 'flip' having the value for 'c' first and 'a' last is intentional). Could anybody programme this (for an array of an unknown number of elements)?
EDIT: I have received no form of schooling at programming/computer science at any pojnt in my life, this is not homework. I am trying to teach myself and I have got stuck; I don't know anybody in person who I could go to for help so I asked here, apologies to those of you who are offended.
EDIT2: I know that this opinion is going to annoy a lot of people; what is the purpose of stackoverflow.com if it is not to exchange information? If I were a child who was stuck with my homework (I'm not) surely that is a valid reason for using stack overflow? Many people on this website seem to have the mindset that if a problem is asked by a beginner then it is not worth answering, which is completely fine because your time is your own. However, what genuinely bugs me is the people who see a question which they deem trivial and say "homework" and vote it down immediately. I think that this website would be far better if there wasn't an "minimum-level" knowledge required in order to ask questions, the "elitist" mindset is just childish in my opinion.
Since this is a learning exercise, here are some hints for you to complete the task yourself:
Prepare a value that will server as the "running total" for your number so far.
Start the running total at zero.
When you convert a number, say, "1234", to an int, this value would first become 1, then 12, then 123, and finally 1234
The final value of the running total is your end result
To go from a previous value to the next, multiply the prior value by ten, and add the value of the current digit to it
Your returnVal does not make sense, because in C you can very often avoid an explicit conversion of char to int. You can definitely avoid it in this case.
Making a function int digit(char c) that returns a value of decimal digit, i.e. c-'a', would be a lot more useful, because it would let you get rid of your c-87 in multiple spots.
char array[SIZE];
long factor=1;
long result=0;
for(int i=0; i<SIZE; i++)
{
result+=returnVal(foo[i])-87)*factor;
factor*=100;
}
This should work for as long as long is large enough to hold the value of 100^the position and, of course, as long as the result does not overflow.