1

I'm currently writing a program that requires a preview of a live display, but the preview, of course, is scaled down. However, when I scale the PictureBox down, the size is incorrect. For the scale to be correct the width and height need to be at a 4:3 ratio. Here's the code:

private void FindOptimalRes(PictureBox picBox)
{
    double h = Height / 4;
    double ratio = 4 / 3;
    picBox.Size = new Size((int)(h * ratio), (int)h);
}

In testing, Height (the height of the form) is 400, so, the width of the new size should be 133. But it always gets resized to 100×100! Why?

Ry-
  • 218,210
  • 55
  • 464
  • 476
Steven
  • 1,709
  • 3
  • 17
  • 27
  • 5
    You should make sure whether YOU have the wrong before say that C# has a math wrong –  Jul 14 '12 at 21:44
  • 4
    Why was this question downvoted? Just because someone is ignorant about something is not a reason for downvoting his question. He even showed his code and everything. – Darin Dimitrov Jul 14 '12 at 21:44
  • 2
    I think, perhaps: "Try to choose a more accurate/issue-reflecting and less combative title .." –  Jul 14 '12 at 21:54
  • This is a good read: http://stackoverflow.com/questions/9841332/why-is-the-division-result-between-two-integers-truncated Also, I've changed your title to make it easier for future visitors with a similar problem to find this post. I see minitech removed your last line - thanks @minitech! – dash Jul 14 '12 at 22:07
  • Okay.. Thank you, Dash. I apologize for my.. noobiness? Whatever. :P Thanks, again. Lol.. – Steven Jul 14 '12 at 22:38
  • So, I know this is an old post, but I just wanted to point out that, at the time of making this question, I was fairly new to C#. I know Java pretty well, but I was not aware that you had to specify that the variables were doubles for them to work in division properly. Just wanted to clear that up.. – Steven Nov 28 '12 at 01:48

6 Answers6

4

4 and 3 are both ints, so it gets turned to 1. Make them something floating-point:

double ratio = 4.0 / 3.0;

Note that you're also making the same mistake with Height (it doesn't matter right now, but it will - change it to 4.0). And if this is the actual code, why divide by four to multiply by four again?

private void FindOptimalRes(PictureBox picBox)
{
    picBox.Size = new Size(Height / 3, Height / 4);
}
Ry-
  • 218,210
  • 55
  • 464
  • 476
3

C#'s math is "correct". The understanding of what is being done is .. missing :-)

The expression 4 / 3 (of type int / int) will evaluate to the integer value 1 as it is using integer division (both operands are integers). The resulting 1 is then implicitly coerced to a double value on assignment.

On the other hand 4d / 3 will "work" (and results in a double 1.333_) because now it is double / int -> double / double (by promotion) -> double using the appropriate floating point division.

Similarly, for Height / 4 (assuming Height is an integer), these would work:

(double)Height / 4          // double / int -> double
Height / 4d                 // int / double -> double
(double)Height / (double)4  // double / double -> double

Happy coding!

  • 1
    For the record, I do know that C#'s math is correct. It's been quite a while since I've programmed in general and nearly a year since in C#, so I simply forgot that little rule. But thank you for the correct answer and for reminding me of this. :P – Steven Jul 14 '12 at 22:10
3

You are doing integer division:

double ratio = 4 / 3; // evaluates to 1

This won't give you the value you are looking for because the decimal point is being truncated, thus evaluating to 1 instead of 1.333. At least one of the operands needs to be a double:

double ratio = 4.0 / 3.0; // evaluates to 1.333

Same goes for Height. Change the 4 to 4.0.

Marlon
  • 19,924
  • 12
  • 70
  • 101
  • Thank you. You realized I was kidding about C#'s math being off and you gave me a straight (and correct) answer. :) – Steven Jul 14 '12 at 21:49
2

Make sure division result is double

double ratio = (double) 4 / 3; // double division 

and no need to set your input values to double.

var num1 = // an integer number
var num2 = // an integer number

//result is integer, because of integer/integer uses 'integer division'
double result = num1 / num2; 

//result is double , because of you forced to 'double division'
double result = (double) num1 / num2;
Ria
  • 10,237
  • 3
  • 33
  • 60
0

Maybe you should do a decimal division and not integer division:

double h = Height / 4.0;
double ratio = 4 / 3.0;

If C# Math was off many things around the world would be off as well.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

You are doing integer division.

what you need to do is this :

private void FindOptimalRes(PictureBox picBox)
{
    double h = Height / 4D; // or Height / 4.0
    double ratio = 4D / 3D; // or 4.0 / 3.0
    picBox.Size = new Size((int)(h * ratio), (int)h); // Size is now correct [133,100]
}

when you do a mathematical operation with an integer literal (no decimal places) it is implicitly typed as an int.

Simply appending a capital D at the end of your literals (4D, 3D) will type them as doubles, and your math will be correct. Alternatively you can write 4.0, 3.0

Dragonalighted
  • 365
  • 1
  • 8