Подтвердить что ты не робот

Сколько значащих цифр у чисел с плавающей и двойной точностью в java?

Есть ли у float 32 двоичных разряда, а double - 64 двоичных цифры? Документация была слишком сложной для понимания.

Все ли биты преобразуются в значимые цифры? Или местоположение десятичной точки занимает несколько бит?

4b9b3361

Ответ 1

float: 32 бит (4 байта), где 23 бит используются для мантиссы (около 7 десятичных цифр). Для экспоненты используются 8 бит, поэтому float может "перемещать" десятичную точку вправо или влево, используя эти 8 бит. Это позволяет избежать накопления большого количества нулей в мантиссе, как в 0,0000003 (3 × 10 -7), или 3000000 (3 × 10 7). В качестве знакового бита используется 1 бит.

double: 64 бит (8 байт), где 52 бит используются для мантиссы (около 16 десятичных цифр). Для экспоненты используются 11 бит, а 1 бит - знаковый бит.

Поскольку мы используем двоичный код (только 0 и 1), один бит в мантиссе неявно равен 1 (оба float и double используют этот трюк), когда число отличное от нуля.

Кроме того, поскольку все находится в двоичном (мантисса и экспоненты), преобразования в десятичные числа обычно не точны. Числа, такие как 0,5, 0,25, 0,75, 0,125, точно сохраняются, но 0,1 нет. Как говорили другие, если вам нужно точно хранить центы, не используйте float или double, используйте int, long, BigInteger или BigDecimal.

Источники:

http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers

http://en.wikipedia.org/wiki/Binary64

http://en.wikipedia.org/wiki/Binary32

Ответ 2

32-разрядное число с плавающей запятой имеет около 7 цифр точности, а 64-разрядное число с двойной точностью имеет около 16 цифр точности

Длинный ответ:

Числа с плавающей точкой состоят из трех компонентов:

  1. Знаковый бит, чтобы определить, является ли число положительным или отрицательным.
  2. Показатель степени, чтобы определить величину числа.
  3. Фракция, которая определяет, насколько далеко между двумя показателями экспоненты число является. Это иногда называют значимым, мантиссой или Коэффициент '

По сути, это работает до sign * 2^exponent * (1 + fraction). Размер' числа, его показатель не имеет значения для нас, потому что он только масштабирует значение доли доли. Зная, что log₁₀(n) дает число цифры n, † мы можем определить точность числа с плавающей запятой с log₁₀(largest_possible_fraction). Потому что каждый бит в поплавке хранит 2 возможности, двоичное число битов n может хранить число до 2ⁿ - 1 (a сумма значений 2ⁿ, где одно из значений равно нулю). Это становится немного hairier, потому что оказывается, что числа с плавающей запятой хранятся с одним меньше доли, чем они могут использовать, потому что нули представлены специально и все ненулевые числа имеют по крайней мере один ненулевой двоичный бит. ‡

Сочетая это, цифры точности для числа с плавающей запятой log₁₀(2ⁿ), где n - количество битов чисел с плавающей запятой дробная часть. 32-разрядное число с плавающей запятой имеет 24-битную дробь для ≈7.22 десятичных цифр точность, и 64-битный двойной имеет 53 бит дроби для ≈15,95 десятичных цифр точности.

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


† По крайней мере, для n ≥ 1 - для других чисел ваша формула будет больше похожа ⌊log₁₀(|n|)⌋ + 1.

‡ 'Это правило по-разному называется соглашением ведущих битов, неявным битом конвенция, или конвенция о скрытых битах. (Wikipedia)

Ответ 3

От спецификация java:

Типы с плавающей запятой являются float и double, которые концептуально связанный с 32-битной и двойной точностью с одной точностью 64-разрядные значения и операции IEEE 754, как указано в IEEE Стандарт для двоичной арифметики с плавающей точкой, стандарт ANSI/IEEE 754-1985 (IEEE, Нью-Йорк).

Как трудно что-либо делать с числами без понимания основ IEEE754, здесь другая ссылка.

Важно понимать, что точность неравномерна и что это не точная память чисел, как это делается для целых чисел.

Пример:

double a = 0.3 - 0.1;
System.out.println(a);          

печатает

0.19999999999999998

Если вам нужна произвольная точность (например, для финансовых целей), вам может понадобиться Big Decimal.

Ответ 4

Обычный математический ответ.

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

При высоком показателе, скажем, 10²³, если изменяется младший значащий бит, появляется большая разница между двумя соседними distinghuishable numbers. Кроме того, десятизначная точка основания 2 делает, что многие базовые номера 10 могут быть только приближены; 1/5, 1/10 - бесконечные числа.

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

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

Ответ 5

Числа с плавающей запятой кодируются с использованием экспоненциальной формы, что-то вроде m * b ^ e, то есть не как целые числа. Вопрос, который вы задаете, будет иметь смысл в контексте номера фиксированных точек. Существует множество арифметических библиотек с фиксированной точкой.

Что касается арифметики с плавающей запятой: число десятичных цифр зависит от представления и системы чисел. Например, существуют периодические числа (0.33333), которые не имеют конечного представления в десятичной форме, но имеют один в двоичном и наоборот.

Также стоит упомянуть, что числа с плавающей точкой до некоторой точки имеют разницу больше единицы, т.е. value + 1 дает value, так как value + 1 не может быть закодировано с помощью m * b ^ e, где m, b и e фиксированы по длине. То же самое происходит при значениях, меньших 1, т.е. Все возможные кодовые точки не имеют одинакового расстояния.

Из-за этого нет точности точно n цифр, подобных номерам с фиксированной точкой, поскольку не каждое число с n десятичными цифрами имеет кодировку IEEE.

Существует почти обязательный документ, который вы должны прочитать после этого, который объясняет числа с плавающей запятой: Что каждый компьютерный ученый должен знать о арифметике с плавающей запятой.

Ответ 6

Посмотрите Float.intBitsToFloat и Double.longBitsToDouble, которые объясняют, как биты соответствуют числам с плавающей запятой. В частности, биты нормального float выглядят примерно так:

 s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW

где A... W - 23 бита - 0s и 1s - представляет дробь в двоичном формате - s +/- 1, представленное 0 или 1 соответственно, а exp - подписанный 8-битный целое число.

Ответ 7

Если мы посмотрим на минимальное положительное значение Float.

Float.MIN_VALUE = 1.4E-45f;
// 0.000000000000000000000000000000000000000000001401298464324817

Таким образом, технически float может содержать до 60 значений, поэтому для диапазонов между (1 и -1) вы, вероятно, захотите использовать только 44 места.

Для общих целей мне нравится находиться между 9995.9995 и -9995.9995 глядя на минимальную точность 0,0001.

Для удовольствия вы можете попробовать:

System.out.println(new DecimalFormat("#####.#####").format(9996.9996f));

Result: 9997

Если мы посмотрим на минимальное положительное значение Double.

Double.MIN_Value = 4.9E-324;
// 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049

Таким образом, технически double может содержать до 326 значений, поэтому для диапазонов между (1 и -1) вы, вероятно, захотите использовать только 324 места.