Плавания округляются в C ++, и я не понимаю, почему - PullRequest
4 голосов
/ 18 июля 2011

Я очень смущен этим ... Вот выдержка из моего кода ..

float m = 0.0, c = 0.0;
printf("toprightx = %d bottomrightx = %d toprighty = %d bottomrighty = %d\n",
    toprightx, bottomrightx, toprighty, bottomrighty);
// find m and c for symmetry line
if (toprightx == bottomrightx) {
  m = (-toprighty + bottomrighty);
}
else {
  m = (-toprighty + bottomrighty) / (toprightx - bottomrightx);
}

c = -toprighty - (m * toprightx);

printf("m = %f and c = %f\n", m, c);

А вот и вывод:

toprightx = 241 bottomrightx = 279 toprighty = 174 bottomrighty = 321
m = -3.000000 and c = 549.000000

Почему выходное округление m и c? Я объявил их как числа с плавающей точкой, поэтому я не понимаю, почему код возвращает целые числа. Правильное значение m должно быть -3,8684.

(Обратите внимание, что toprightx, bottomrightx, toprighty, bottomrighty были объявлены как целые числа далее в коде.)

Ответы [ 7 ]

14 голосов
/ 18 июля 2011

Обратите внимание, что toprightx, bottomrightx, toprighty, bottomrightty были далее в коде объявлены как целые числа.

Вот твой ответ. Вычисления, которые включают только целые числа, выполняются в целочисленной математике, включая деления. Неважно, что результат присваивается поплавку.

Чтобы исправить это, либо объявите хотя бы одно из значений x / y как float, либо приведите его к плавающему в расчете.

7 голосов
/ 18 июля 2011

Вы выполняете целочисленное деление в этой строке:

(-toprighty + bottomrighty) / (toprightx - bottomrightx);

Поскольку topright, bottomrightty, toprightx и bottomrightx - все целые числа, результатом этого уравнения также будет целое число. После того, как уравнение вычисляет целое число, вы назначаете его на число с плавающей точкой. Это эквивалентно:

float m = -3;

Вы можете сделать что-то вроде этого:

(-toprighty + bottomrighty + 0.0) / (toprightx - bottomrightx);
5 голосов
/ 18 июля 2011

Вот вам int:

m = (-toprighty + bottomrighty) / (toprightx - bottomrightx);
       ^int        ^int              ^int        ^int

Все эти операции будут выполняться с использованием целочисленного деления (усечения чисел с плавающей запятой) и затем приводятся к float.Попробуйте вместо:

m = float(-toprighty + bottomrighty) / (toprightx - bottomrightx);
3 голосов
/ 18 июля 2011

Это потому, что вы используете только int для своих вычислений, поэтому C ++ использует целочисленные вычисления для них. Просто приведите одну из ваших переменных int к float, и все будет хорошо.

Изменение этого утверждения m = (-toprighty + bottomrighty) / (toprightx - bottomrightx); на m = (-toprighty + bottomrighty) / (float)(toprightx - bottomrightx); сделает это.

2 голосов
/ 18 июля 2011

Приведение (неявно, как вы делаете) значения с плавающей точкой к int усекает данные, которые не вписываются в новый тип.

Обратите внимание, что ваши данные тоже не округляются, они усекаются.

2 голосов
/ 18 июля 2011

объявляйте toprightx, bottomrightx, toprightty, bottomrightty как поплавки или приводите их к поплавкам, прежде чем запрашивать смешанную арифметику.

1 голос
/ 18 июля 2011

Попробуйте привести делитель к числу с плавающей точкой, чтобы деление использовало арифметику с плавающей точкой:

m = (-toprighty + bottomrighty) / (float)(toprightx - bottomrightx);
...