Почему там различие между тем же значением, сохраненным как плавание и двойным в Java?

hackish решение могло бы состоять в том, чтобы использовать разметку как это:

<button><span>Go</span></button>

и применяют Ваши стили границ к элементу промежутка.

5
задан Shog9 1 October 2009 в 17:03
поделиться

5 ответов

Это потому, что ближайшее значение с плавающей запятой к 1,3 не совпадает с ближайшим двойным значением к 1,3. Ни одно из значений не будет точно 1,3 - это не может быть точно представлено в неповторяющемся двоичном представлении.

Чтобы дать другое понимание того, почему это происходит, предположим, что у нас есть два десятичных типы с плавающей запятой - decimal5 и decimal10 , где число представляет количество значащих цифр. Теперь предположим, что мы попытались присвоить им обоим значение «треть». Вы получите

decimal5 oneThird = 0.33333
decimal10 oneThird = 0.3333333333

. Очевидно, что эти значения не равны. Здесь точно то же самое, только с другими задействованными базами.

Однако, если вы ограничите значения менее точным типом, вы ' Я обнаружу, что они равны в данном конкретном случае :

double d = 1.3d;
float f = 1.3f;
System.out.println((float) d == f); // Prints true

Однако это не гарантируется. Иногда приближение от десятичного литерала к двойному представлению, а затем приближение этого значения к представлению с плавающей запятой оказывается менее точным, чем прямое десятичное приближение к плавающему. Один из примеров этого 1.0000001788139343 (спасибо stephentyrone за обнаружение этого примера).

Более безопасно, вы можете провести сравнение между двойными числами, но используйте литерал float в исходном присвоении:

double d = 1.3f;
float f = 1.3f;
System.out.println(d == f); // Prints true

In в последнем случае это немного похоже на высказывание:

decimal10 oneThird = 0.3333300000

Однако , как указано в комментариях, вы почти наверняка не должны сравнивать значения с плавающей запятой с ==. Это' s почти никогда не правильный поступок именно из-за такого рода вещей. Обычно, если вы хотите сравнить два значения, вы делаете это с помощью какого-то «нечеткого» сравнения равенства, проверяя, являются ли эти два числа «достаточно близкими» для ваших целей. Дополнительную информацию см. На странице Java Traps: double .

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

26
ответ дан 18 December 2019 в 05:17
поделиться

Число с плавающей запятой - это число с плавающей запятой одинарной точности. Double - это число с плавающей запятой двойной точности. Подробнее здесь: http://www.concentric.net/~Ttwang/tech/javafloat.htm

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

Например:

float a = 1.3f;
double b = 1.3;
float delta = 0.000001f;
if (Math.abs(a - b) < delta)
{
    System.out.println("Close enough!");
}
else
{
    System.out.println("Not very close!");
}

Некоторые числа не могут быть представлены точно с плавающей запятой (например, 0,01 ), поэтому вы можете получить неожиданные результаты при сравнении на предмет равенства.

11
ответ дан 18 December 2019 в 05:17
поделиться

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

2
ответ дан 18 December 2019 в 05:17
поделиться

Прочтите эту статью .

Вышеупомянутая статья наглядно иллюстрирует ваш сценарий с использованием типов double и float.

2
ответ дан 18 December 2019 в 05:17
поделиться
float a=1.3f;
double b=1.3; 

На этом этапе у вас есть две переменные, содержащие двоичные приближения к вещественному числу 1.3. Первое приближение имеет точность примерно до 7 десятичных цифр, а второе - примерно до 15 десятичных цифр.

if(a==b) { 

Выражение a == b вычисляется в два этапа. Сначала значение a преобразуется из float в double путем дополнения двоичного представления. Результат по-прежнему имеет точность примерно до 7 десятичных цифр, как представление Real 1.3. Затем вы сравниваете два разных приближения. Поскольку они разные, результатом a == b будет false .

Следует усвоить два урока:

  1. Литералы с плавающей запятой (и двойные) почти всегда приближения; например фактическое число, которое соответствует литералу 1.3f , не совсем равно действительному числу 1.3 .

  2. Каждый раз, когда вы выполняете вычисления с плавающей запятой, появляются ошибки. построить. Поэтому, когда вы сравниваете числа с плавающей запятой / двойные числа, обычно ошибочно использовать простые символы «==», «<» и т. Д. Вместо этого вы должны использовать | a - b | <дельта , где дельта выбрана соответствующим образом. (И определение подходящей дельты также не всегда прямолинейно.)

  3. Вам следовало пройти этот курс численного анализа: -)

2
ответ дан 18 December 2019 в 05:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: