Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
926 views
in Technique[技术] by (71.8m points)

c++ - Why is my double or int value is always 0 after division?

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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 << "
with    cast: "<< outval2 << std::endl;

    return 0;
}

The output of this is:

without cast: 9
with    cast: 12.8571

See it here

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...