I'm fairly new to C++ and I'm experiencing some strange behaviour from a percentage increase method I am writing for some image editing software.
What I want to do is give the R G or B value of the current pixel and divide it by some modifier, then multiply it by the new value to return the percentage increase, fairly easy concept.
However, whenever I run my debugger, the return value is always 0, I thought this may be because I was trying to do operations which give negative numbers on an integer (or maybe a divide by zero could occur?), so I tried to use a double to store the output of the computation, however I've had no luck.
The code I'm struggling with is below:
int Sliders::getPercentageIncrease(int currPixel, int newValue, int modifier)
{
// calculate return value
double returnVal = (currPixel / modifier) * newValue;
// Check we are returning a positive integer
if(returnVal >= 0)
return (int)returnVal;
// Return a negative integer value
return (int)(0 - returnVal);
}
What am I doing wrong here?
NOTE: I have checked values, of inputs in my debugger and I get stuff like:
currPixel = 30
newValue = 119
modifier = 200
From this I would expect an output of 18 (I am not concerned with returning decimal figures)
Your current calculation only involves integers and so will be affected by integer division (which truncates the result to the nearest integer value).
(currPixel / modifier) * newValue
| |
---------------integer division e.g. 10/3 = 3, not 3.333
The result is then cast to double, but the accuracy is lost before this point.
Consider the following:
#include <iostream>
using namespace std;
int main() {
int val1 = 10;
int val2 = 7;
int val3 = 9;
double outval1 = (val1 / val2) * val3;
double outval2 = ((double)val1 / val2) * val3;
cout << "without cast: " << outval1 << "\nwith cast: "<< outval2 << std::endl;
return 0;
}
The output of this is:
without cast: 9
with cast: 12.8571
Note that the cast has to be applied in the right place:
(double)(val1 / val2) * val3 == 9.0 //casts result of (val1/val2) after integer division
(val1 / val2) * (double)val3 == 9.0 //promotes result of (val1/val2) after integer division
((double)val1 / val2) * val3 == 12.8571 //promotes val2 before division
(val1 / (double)val2) * val3 == 12.8571 //promotes val1 before division
Due to promotion of the other operands, if in doubt you can just cast everything and the resulting code will be the same:
((double)val1 / (double)val2) * (double)val3 == 12.8571
It is a little more verbose though.