Ваша формула интеграции выглядит правильно для дискретных точек. У меня проблемы с пониманием того, как вы хотите область под кривой. Кстати, как вы написали это, не отсортированные по оси X, это получение области под линией из точки [0] в точку [1], а затем вычитание области из точки [1] в точку [2]. Если это ваш случай, то это работает.
Если вы хотите, чтобы они находились под всеми тремя точками, я бы отсортировал xs. Если вы хотите получить площадь под кривой, даже если учесть, что она удваивается назад, я бы взял абсолютное значение x в цикле for. abs ()
Если вы хотите область под кривой без двойного счета области между точкой [1] и точкой [2]. Я бы написал,
import matplotlib.pyplot as plt
xs = [2, 5, 4]
x_sort = sorted(xs)
ys = [6, 7, 8]
sum = 0
plt.plot(xs, ys, 'bo')
plt.show()
for i in range(1, len(xs)):
slope = (xs[i]-xs[i-1])/(ys[i] - ys[i-1])
delta_x = x_sort[i] - x_sort[i - 1]
delta_y = ys[i - 1] + (ys[i-1] + delta_x * slope)
sum = sum + (delta_y/2 * delta_x)
print(sum)
Это берет наклон между несортированными точками и применяет его к отсортированным значениям, давая вам область непосредственно под графиком, если вы соединили линии в порядке [xs , ys] пары.
Надеюсь, это поможет ответить на ваш вопрос.
Я использовал бы что-то как:
BigDecimal result = new BigDecimal("50.5399999").setScale(2, BigDecimal.ROUND_HALF_UP);
Существует большая статья под названием, Делают центы с BigDecimal на JavaWorld, на который необходимо смотреть.
Необходимо использовать десятичное число или тип валюты для представления денег, не плавающей точки.
Если Вы делаете вычисления валюты, я думаю, что можно копаться в проблемах, которые кажутся простыми в их поверхности, но на самом деле довольно сложны. Например, округление методов, которые являются результатом решений бизнес-логики, которые повторяются часто, может решительно влиять на общие количества вычислений.
Если это будет домашней работой, показывая учителю, что Вы продумали реальную проблему, а не просто бросили набор кода вместе, который "работает" - конечно, будет более впечатляющим.
На ноте стороны я первоначально собирался предложить смотреть на реализацию математических методов Java в исходном коде, таким образом, я смотрел. Я заметил, что Java использовал собственные методы для своего округления методов - точно так же, как он должен.
Однако взгляд на BigDecimal показывает, что существует источник Java, доступный для округления в Java. Так, а не просто дают Вам код для Вашей домашней работы, я предлагаю, чтобы Вы посмотрели на закрытый метод BigDecimal doRound (мГц MathContext) в источнике Java.
Почему Вы не хотели бы использовать какие-либо Математические функции?
static long round(double a)
- Возвращает самое близкое долго к аргументу.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html
Для представления денег, я послушал бы следующий совет вместо изобретения велосипед:
Если 50.54 не будет представимым в двойной точности, то округление не поможет.
При попытке преобразовать 50.53999999 в целое число долларов и целое число центов, сделайте следующее:
double d = 50.539999; // or however many 9's, it doesn't matter
int dollars = (int)d;
double frac = d - dollars;
int cents = (int)((frac * 100) + 0.5);
Обратите внимание, что добавление 0,5 на том последнем шаге к раунду к ближайшему целому числу центов. Если Вы всегда хотите, чтобы это окружило, изменило это для добавления 0.9999999 вместо 0,5.
Попытайтесь хранить свою валюту как количество центов (Вы могли абстрагировать это к количеству основы curreny единицы) с длинным.
Править: Так как это - домашняя работа, Вы не можете управлять типами. Считайте это уроком для будущих проектов
long money = 5054;
long cents = money % 100;
long dollars = money / 100; // this works due to integer/long truncation
System.out.printf("$%d.%02.d", dollars, cents);
Необходимо сделать номер.535 и сравнить это с исходным числом, чтобы видеть, окружите ли Вы или вниз. Вот то, как Вы добираетесь.535 от.53999999 (должен работать на любое число):
num = .53999999;
int_num = (int)(num * 100); // cast to integer, however you do it in Java
compare_num = (int_num + 0.5) / 100;
compare_num
был бы.535 в этом случае. Если num
больше, чем или равен compare_num
, окружите к int_num + 1
. Иначе округлите в меньшую сторону просто до int_num
.
У Sean, кажется, есть он, если не Вы хотите навязать надлежащие правления затем, можно хотеть добавить если оператор как так:
double value = .539999;
int result = (int) (value*100);
if(((value*100)%result)>.5)
result++;
Я предлагаю, чтобы Вы использовали, очень хотят округлять двойное значение. Это не будет иметь значения для небольших чисел, но могло иметь значение.
double d = 50.539999;
long cents = (long)(d * 100 + 0.5);
double rounded = cents/100;
Что точно Вы пытаетесь сделать? Вы всегда пытаетесь перейти к двум цифрам? Или Вы всегда пытаетесь починить вещи как 99 999 в конце независимо от того, что?
Согласно комментариям, это - на самом деле первый: округление к долларам и центам. Так действительно просто round(100*a)/100
то, что Вы хотите. (Последний был бы намного более сложным...),
Наконец, если бы Вы просто хотите извлечь часть центов, следующее работало бы:
dollars_and_cents = round(100*a)/100
cents = (dollars_and_cents-(int)dollars_and_cents)*100
(или делает Java, просто имеют frac
? В этом случае последняя строка просто была бы frac(dollars_and_cents)*100
.