Математический расчет не работает, как ожидалось - PullRequest
4 голосов
/ 05 марта 2009

У меня есть следующее в программе (часть гораздо большей функции, но это соответствующий бит тестирования):

int test = 100 + (100 * (9 / 100));
sprintf (buf, "Test: %d\n\r", test);
display_to_pc (buf, player);

В основном это составляет:

x = a + (a * (b / 100))

Где a - заданная цифра, b - процентный модификатор, а x - результат (оригинал плюс процент от оригинала) ... Надеюсь, это имеет смысл.

Это дает мне:

Test: 100

Я думал, что математика в моей голове может быть неправильной, но я проверил несколько калькуляторов и даже оценщик выражений в моей IDE, и все они дают мне ожидаемый результат 109 для первого выражения.

Может ли кто-нибудь просветить меня, что мне здесь не хватает?

Большое спасибо. :)

Ответы [ 11 ]

14 голосов
/ 05 марта 2009

Заменить

int test = 100 + (100 * (9 / 100));

с

int test = 100 + (100 * 9 / 100);
// x = a + (a * b / 100)

и все будет работать как положено. 9 / 100 выполняется с использованием целочисленного деления; ближайшее целое число к .09 равно 00 * 100 по-прежнему 0).

Выполнение умножения сначала приводит к 900 / 100, что дает вам 9, что вы ожидали.

Если вам нужна точность, превышающая целочисленную, вам может понадобиться пройти маршрут с плавающей запятой.

8 голосов
/ 05 марта 2009

Вы используете целочисленную математику.

9/100 = 0.

100 + (100 * (0) = 100.

Ваши калькуляторы используют математические вычисления с плавающей запятой и могут обрабатывать десятичные дроби соответствующим образом.

4 голосов
/ 05 марта 2009

Как уже отмечали другие, проблема в том, что вы делаете целочисленную арифметику. Вы должны выполнить вычисление как число с плавающей запятой, приведя переменную к удвоению или используя двойную константу, а затем разрешите усечение, чтобы получить только целую часть.

x = a + (a * (b / 100.0));

или

x = a + (a * ((double)b / 100)));
3 голосов
/ 05 марта 2009

Ваша ошибка в том, что 9/100 интерпретируется как целочисленное деление и имеет значение 0, а не 0,09.

Вместо этого вы можете написать 9 / 100.0 или переставить выражение.

3 голосов
/ 05 марта 2009

int test = 100 + (100 * (9/100));

9/100 = 0

0 * 100 = 0

100 + 0 = 100

2 голосов
/ 05 марта 2009

Используйте ответ Daniel L, если вы будете работать только с выражениями, которые приведут к целым целым значениям. Если значения, с которыми вы будете работать, менее чисты, используйте двойные литералы вместо целочисленных:

int test = 100.0 + (100.0 * (9.0 / 100.0));
2 голосов
/ 05 марта 2009

вы используете целочисленное деление, поэтому 9/100 равно нулю, поэтому test = 100 + 0 = 100

1 голос
/ 05 марта 2009

Вы должны использовать арифметику с плавающей запятой, чтобы 9/100 стало 0,09.

int test = 100,0 + (100,0 * 9,0 / 100,0);

1 голос
/ 05 марта 2009

Изменение:

int test = 100 + (100 * (9 / 100));

до

int test = (int)(100 + (100 * (9 / 100.0)));

и посмотрите, работает ли он должным образом.

РЕДАКТИРОВАТЬ: вау. Много ответов, пока я печатал. Большинство из них тоже будут работать.

1 голос
/ 05 марта 2009

Ответ 9/10 усекается до 0, а затем вы умножаете его на 100, а затем добавляете к нему 100.

...