-1

I'm actually totally stuck I don't understand the behavior of this function:

#include <stdio.h>

typedef struct s_resolution
{
   int x;
   int y; 
   float fx;
   float fy;
} t_resolution;

typedef struct s_pixel_info
{
    int tablen;
    t_resolution resolution;
    char name;
    int line;
    int pos_suite[6];
    int suite[6];
} t_pixel_info;

void get_proportion_ratio(t_pixel_info DataB, t_pixel_info pix_info,
                           t_resolution *proportion)
{
    proportion->fx = (float)(DataB.resolution.x / pix_info.resolution.x);
    //I also tried without the cast
    proportion->y = (int)(DataB.resolution.y / pix_info.resolution.y * 100);
    //if (proportion->y != 100)
    printf("%d | %d | %d\n",proportion->y, DataB.resolution.y, pix_info.resolution.y);
}

int main()
{
  t_pixel_info DataB;
  t_pixel_info pix_info;
  t_resolution proportion;

  DataB.resolution.x = 5;
  pix_info.resolution.x = 10;
  DataB.resolution.y = 5;
  pix_info.resolution.y = 10;
  get_proportion_ratio(DataB, pix_info, &proportion);

}

DataB.resolution.y, pix_info.resolution.y and proportion->y are all Int type.
My problem is that I have this result:

0 | 5 | 10

The operation only works when the result is 100... I must be missing something obvious but I've no idea what.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
Cjdcoy
  • 317
  • 1
  • 2
  • 12
  • 2
    Are you stuck with integer division issues? – Sourav Ghosh Nov 17 '17 at 10:06
  • Try this `proportion->fx = (DataB.resolution.x / (float)pix_info.resolution.x);` – Szabolcs Nov 17 '17 at 10:06
  • 2
    Please post a [mcve]. And show clearly what you expect and what you get instead – Jabberwocky Nov 17 '17 at 10:07
  • Try this: `(float)(DataB.resolution.x / pix_info.resolution.x);` -> `((float)DataB.resolution.x / pix_info.resolution.x);` – Jabberwocky Nov 17 '17 at 10:09
  • And also `(int)(DataB.resolution.y / pix_info.resolution.y * 100);` -> `((100 * DataB.resolution.y) / pix_info.resolution.y);` – Jabberwocky Nov 17 '17 at 10:11
  • Please [edit] your code to reduce it to a [mcve] of your problem. Your current code includes much that is peripheral to your problem - a minimal sample normally looks similar to a good unit test: only performing one task, with input values specified for reproducibility. – Toby Speight Nov 17 '17 at 10:16

2 Answers2

2

All of your divisions are being done on integers. Take this expression:

5 / 10 * 100

This groups as:

(5 / 10) * 100

This evaluates to 0: 5 / 10 is 0, and 0 * 100 is still 0. Casting the result after the fact doesn't change it.

If you multiply by 100 before you divide, you will obtain two more digits of precision:

100 * 5 / 10

This evaluates to 50: 100 * 5 is 500, and 500 / 10 is 50.

You could also perform the arithmetic in floating point, e.g.

(double) 5 / (double) 10 * (double) 100

Or you could just cast the first operand and let the standard arithmetic conversions handle the rest; the result is equivalent:

(double) 5 / 10 * 100

In either case, the result will be 50.0

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
1

Since resolution.x and resolution.y are ints, the division between them will done as integer division, which keeps only the "whole" part of the division. If you want to perform a floating point ("regular") division, you should cast to a floating point type before performing the division. E.g.:

proportion->fx = ((float) DataB.resolution.x) / ((float) pix_info.resolution.x);
Mureinik
  • 297,002
  • 52
  • 306
  • 350