Существуют ли какие-либо стандартные реализации IEEE 754 для примитивов с плавающей точкой Java?
Меня интересует, использует ли Java стандарт IEEE 754 для реализации своей арифметики с плавающей запятой. Здесь я видел такую вещь в документации:
операция, определенная в IEEE 754-2008
Как я понимаю, положительной стороной IEEE 754 является повышение точности арифметики с плавающей запятой, поэтому, если я буду использовать double
или же float
в Java порядок вычислений будет таким же, как в BigDecimal
? И если нет, то какой смысл использовать стандарт IEEE 754 в Math
учебный класс?
1 ответ
Меня интересует, использует ли Java стандарт IEEE 754 для реализации арифметики с плавающей запятой.
IEEE-754 определяет стандарты для нескольких типов с плавающей точкой. В течение многих лет все они были двоичными числами с плавающей точкой; это то, что Java float
а также double
являются: float
является 32-битным двоичным значением IEEE-754 с плавающей запятой (то, что стандарт называет binary32
). double
является 64-битным (что называет стандарт binary64
). Эти двоичные числа с плавающей запятой очень эффективны для вычислений компьютеров, но поскольку они работают в двоичном формате, а мы - в десятичном, существуют некоторые несоответствия ожидания; например, 0.1
не может быть сохранен именно в double
и вы получите странности, как 0.1 + 0.2
оказывается 0.30000000000000004
, См. Математика с плавающей точкой сломана? для деталей. Например, они не являются хорошим выбором для финансовых расчетов.
BigDecimal
класс Java, который реализует десятичные дробные числа с произвольной точностью Это намного медленнее, чем при использовании double
, но результаты соответствуют нашим десятичным ожиданиям (например, что 0.1 + 0.2
будет 0.3
).
В выпуске IEEE-754 2008 года добавлены новые важные форматы, в частности decimal32
, decimal64
, а также decimal128
, Это десятичные числа с плавающей запятой, и поэтому они работают так же, как и мы. 0.1
может быть точно сохранено в decimal64
, 0.1 + 0.2
является 0.3
в decimal64
, Однако, насколько я могу судить, они на самом деле не имеют отношения к вашему вопросу.
поскольку BigDecimal
предшествующий IEEE-754 2008 (с некоторым отрывом), он определяет свою собственную семантику.
А если нет, то какой смысл использовать стандарт IEEE 754 в классе математики?
JDK9 добавляет новые операции в Math
которые делают вещи, определенные спецификацией IEEE-754 2008 (например, fma
, который выполняет плавное умножение-сложение), и поэтому для ясности определяет эти операции со ссылкой на спецификацию IEEE-754 2008.
Больше чтения:
- IEEE-754 в Википедии
BigDecimal
JavaDoc