2010-06-01 4 views
38

Я создаю калькулятор RPN для школьного проекта. У меня возникают проблемы с оператором модуля. Поскольку мы используем двойной тип данных, модуль не будет работать с числами с плавающей запятой. Например, 0.5% 0.3 должно возвращать 0.2, но я получаю деление на нулевое исключение.Как использовать модуль для float/double?

В инструкции говорится использовать fmod(). Я везде искал fmod(), включая javadocs, но я не могу его найти. Я начинаю думать, что это метод, который мне нужно будет создать?

Редактировать: hmm, странно. Я снова включил эти цифры, и кажется, что он работает нормально ... но на всякий случай. Нужно ли отслеживать использование оператора mod в Java при использовании плавающих типов? Я знаю, что нечто подобное не может быть сделано на C++ (я думаю).

ответ

59

Возможно, у вас была опечатка, когда вы ее впервые запустили.

Оценка 0.5 % 0.3 возвращает '0.2' (A double), как ожидалось.

У Mindprod есть good overview of how modulus works на Java (посмотрите на конец для модуля с плавающей точкой).

+1

но '1.0% 0.1' возвращает ...' 0.09999999999999995', в результате ошибки округления. Любая идея, как исправить это (предположительно с значениями эпсилон?) – Groostav

+1

Ошибки округления всегда будут выполняться в вычислениях с плавающей запятой. Либо возьмите значение, как оно указано, либо округлите его до ближайшего необходимого значения. – Anarchofascist

+0

'String.format ("%. 8f ", 1.0% 0.1)' возвращает '0.10000000' – Anarchofascist

5

Я думал, что оператор регулярного модуля будет работать для этого в java, но его не может быть сложно закодировать. Просто разделите числитель на знаменатель и возьмите целочисленную часть результата. Умножьте это на знаменатель и вычтите результат из числителя.

x = n/d 
xint = Integer portion of x 
result = n - d * xint 
2

fmod - стандартная функция C для обработки модуля с плавающей запятой; Я предполагаю, что ваш источник говорил, что Java обрабатывает модуль с плавающей запятой так же, как и функция C fmod. В Java вы можете использовать % оператор в парном же, как и на целых:

int x = 5 % 3; // x = 2 
double y = .5 % .3; // y = .2 
37

В отличие от C, Java позволяет использовать% как для целого числа и с плавающей точкой и (в отличие от C89 и C++) это хорошо определено для все входы (в том числе негативы):

JLS §15.17.3 от:

результат с плавающей точкой операции остаток определяется правилами IEEE арифметики:

  • Если один из операндов NaN, результатом является NaN.
  • Если результат не NaN, знак результата равен знаку дивиденда.
  • Если дивиденд - бесконечность, либо делитель равен нулю, либо оба, результат равен NaN.
  • Если дивиденд конечен и делитель бесконечен, результат равен дивиденду.
  • Если дивиденд равен нулю и делитель конечен, результат равен дивиденду.
  • В остальных случаях, когда ни бесконечность, ни ноль, ни NaN вовлечен, с плавающей точкой остаток г от деления дивидендов п дивизором D определяется математическим соотношением г = n- (d · q) , где q - целое число, которое является отрицательным , только если n/d отрицательно и положительно , только если n/d является положительным и величина как можно больше без превышения величины истинный математический фактор n и d.

Итак, для вашего примера 0,5/0,3 = 1,6 .... q имеет тот же знак (положительный) как 0,5 (дивиденд), а величина равна 1 (целое с наибольшей величиной, не превышающей величину 1,6 ...), и r = 0,5 - (0,3 * 1) = 0,2

+2

Последний пулевой пункт - это стена с текстом. Было бы яснее сказать, что на примере: '0,5% 0,3 = 0,2' и' (-0,5)% 0,3 = -0,2' – GameDeveloper