Как сравнить double java

от admin

Class Double

In addition, this class provides several methods for converting a double to a String and a String to a double , as well as other constants and methods useful when dealing with a double .

This is a value-based class; programmers should treat instances that are equal as interchangeable and should not use instances for synchronization, or unpredictable behavior may occur. For example, in a future release, synchronization may fail.

Floating-point Equality, Equivalence, and Comparison

An equivalence relation on a set of values is a boolean relation on pairs of values that is reflexive, symmetric, and transitive. For more discussion of equivalence relations and object equality, see the Object.equals specification. An equivalence relation partitions the values it operates over into sets called equivalence classes. All the members of the equivalence class are equal to each other under the relation. An equivalence class may contain only a single member. At least for some purposes, all the members of an equivalence class are substitutable for each other. In particular, in a numeric expression equivalent values can be substituted for one another without changing the result of the expression, meaning changing the equivalence class of the result of the expression.

  • If v1 and v2 are both NaN, then v1 == v2 has the value false . Therefore, for two NaN arguments the reflexive property of an equivalence relation is not satisfied by the == operator.
  • If v1 represents +0.0 while v2 represents -0.0 , or vice versa, then v1 == v2 has the value true even though +0.0 and -0.0 are distinguishable under various floating-point operations. For example, 1.0/+0.0 evaluates to positive infinity while 1.0/-0.0 evaluates to negative infinity and positive infinity and negative infinity are neither equal to each other nor equivalent to each other. Thus, while a signed zero input most commonly determines the sign of a zero result, because of dividing by zero, +0.0 and -0.0 may not be substituted for each other in general. The sign of a zero input also has a non-substitutable effect on the result of some math library methods.

For ordered comparisons using the built-in comparison operators ( < , <= , etc.), NaN values have another anomalous situation: a NaN is neither less than, nor greater than, nor equal to any value, including itself. This means the trichotomy of comparison does not hold.

To provide the appropriate semantics for equals and compareTo methods, those methods cannot simply be wrappers around == or ordered comparison operations. Instead, equals defines NaN arguments to be equal to each other and defines +0.0 to not be equal to -0.0 , restoring reflexivity. For comparisons, compareTo defines a total order where -0.0 is less than +0.0 and where a NaN is equal to itself and considered greater than positive infinity.

The operational semantics of equals and compareTo are expressed in terms of bit-wise converting the floating-point values to integral values.

The natural ordering implemented by compareTo is consistent with equals. That is, two objects are reported as equal by equals if and only if compareTo on those objects returns zero.

The adjusted behaviors defined for equals and compareTo allow instances of wrapper classes to work properly with conventional data structures. For example, defining NaN values to be equals to one another allows NaN to be used as an element of a HashSet or as the key of a HashMap . Similarly, defining compareTo as a total ordering, including +0.0 , -0.0 , and NaN, allows instances of wrapper classes to be used as elements of a SortedSet or as keys of a SortedMap .

Подводные камни Java. Часть 1

С какими трудностями встречается начинающий разработчик java?

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

Цель данной публикации:
Показать наиболее часто встречающиеся ошибки начинающих и некоторые приемы их исправления. Понятно, что некоторые ошибки могут быть сложными и происходить по тем или иным причинам. Цель публикации в некоторой степени проанализировать их и помочь выявить на раннем этапе. Надеюсь данная публикация будет полезна начинающим.

Контрольный список ошибок:

  1. Опечатки. Досадные опечатки, которые не сразу обнаруживаются
  2. Присвоение в условии вместо сравнения
  3. Логические ошибки в условии
  4. Неправильное сравнение строк
  5. Неправильная инициализация переменных примитивных типов
  6. Неправильное использование double
  7. Неправильный тип возвращающего значения в конструкторе.
  8. Деление на ноль. POSITIVE_INFINITY
  9. Не учет порядка инициализации класса
  10. Локальная переменная скрывает переменную класса
  11. Игнорирование автоматически приведение типов в арифметических выражениях
  12. Бесконечный цикл с byte, который трудно обнаружить.
  13. Имя класса отличается от имени файла, в котором он хранится.
  14. Не проинициализированы объекты, являющиеся элементами массива.
  15. Помещение в один файл сразу нескольких классов с модификатором public

Подводные камни Java

Все языки программирования имеют свои достоинства и недостатки. Это обусловлено многими причинами. Язык Java не исключение. Я попытался собрать некоторые очевидные и не очевидные трудности, с которыми сталкивается начинающий программист Java. Уверен, что опытные программисты также найдут в моей статье что-то полезное. Практика, внимательность и полученный опыт программирования, помогут избавить вас от многих ошибок. Но некоторые ошибки и трудности лучше рассмотреть заранее. Я приведу несколько примеров с кодом и объяснениями. Многие объяснения вам станут понятны из комментариев к коду. Практика дает очень многое, так как некоторые правила не столь очевидны. Некоторые лежат на поверхности, некоторые скрыты в библиотеках языка или в виртуальной машине java. Помните, что java это не только язык программирования с набором библиотек, это еще и виртуальная машина java.

Для статьи я специально написал работающий код с подробными комментариями. Для написания статьи с примерами кода использовалась java 8. Для тестирования код java помещен в отдельные пакеты.

Пример: «package underwaterRocks.simple;»

С какими трудностями сталкиваются начинающие?

Опечатки

Бывает так, что начинающие программисты делают опечатки, которые трудно обнаружить с первого взгляда.

Пример кода:

Объяснение: «Точка с запятой означает конец оператора. В данном случае ‘;’ — это конец пустого оператора. Это логическая ошибка. Такую ошибку бывает трудно обнаружить.

Компилятор сочтет, что всё правильно. Условие if(ival>0); в данном случае не имеет смысла. Потому как означает: если ival больше ноль, ничего не делать и продолжить. Очевидное решение — убрать точку с запятой.»

Присвоение в условии вместо сравнения

В условии присвоение переменной.

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

В данном коде if(myBool = true) означает: «Присвоить переменной myBool значение true,
если выражение истинно, выполнить условие следующее за скобками.»

В данном коде условие будет всегда истинно. И System.out.println(myBool); будет выполнено всегда, независимо от условия.

== — это сравнение на равенство.
= — это присвоение, вы можете проговорить a = 10; как: «а присвоить значение 10».

Условие в скобках возвращает логическое значение.
Не важно в каком порядке вы запишите. Вы можете сравнить так: (0 == a) или (5 == a)
Если вы забудете один знак равенства, например так (0 = a) или (5 = a), то компилятор сообщит вам об ошибке. Вы присваиваете значение, а не сравниваете.
Вы также можете записать в удобочитаемой форме какой-то интервал.
Например: вам нужно написать: a больше 5 и меньше 10.
Вы пишите так: (a>4 && a<10), но с таким же успехом вы можете написать: (4<a && a<10),
теперь вы видите, что a находится в интервале между 4 и 10, исключая эти значения. Это более наглядно. Сразу видно, что, значение переменной а находится в интервале между 4 и 10 ( ]4,10[ ), исключая эти граничные значения.

Читать:
Как снять ачх колонки

Пример в коде(интервал ]3,9[ ):
if(3<a&&a<9) выполнить;

Логическая ошибка

if(условие)<> if(условие)<> else<> — else относится к ближайшему if.
Часто это бывает причиной ошибок начинающих.

Неправильное сравнение строк

Начинающие довольно часто используют == вместо .equals для сравнения строк.

Инициализация переменных

Рассмотрим инициализацию переменных примитивного типа.

Примитивы (byte, short, int, long, char, float, double, boolean).

Локальные переменные немного отличаются;
Компилятор никогда не присваивает значение по умолчанию неинициализированной локальной переменной.

Если вы не можете инициализировать свою локальную переменную там, где она объявлена,
не забудьте присвоить ей значение, прежде чем будете её использовать.

Доступ к неинициализированной локальной переменной приведет к ошибке времени компиляции.

Подтверждение этого примечания в коде:

На что следует обращать внимание при инициализации переменной.

На диапазон значений переменной данного типа. На то, что переменная инициализируется литералом определенного типа. На явное и неявное приведение типов. На совместимость типов.

При использовании оболочек типа Integer, следует обратить внимание на авто упаковку и авто распаковку данных типов.

Неправильное использование double

Здесь нужно пояснить. Речь идет не о неправильном использовании типа double.
Используем мы правильно. Только результат может удивить начинающего программиста.
Файл: «MinusDouble.java»

Как мы видим в коде два метода с одинаковыми именами: MyConstructor() и MyConstructor(). Один из методов ничего не возвращает. Это и есть конструктор нашего класса. Другой метод с void — это обычный метод класса. В случае, когда вы не создали конструктор или создали, по вашему мнению конструктор класса с void, то компилятор создаст конструктор по умолчанию и вы будете удивлены, почему ваш конструктор не работает.

Деление на ноль

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

Выполнение кода выведет:

Деление целого типа на ноль даст ArithmeticException.

В классе java.lang.Double определена константа POSITIVE_INFINITY;

Она преобразуется в строку равную Infinity.

Порядок инициализации

Вначале выполняются все статические блоки, затем блоки инициализации, затем конструктор класса.

Выведется: «123 Конструктор»

Локальная переменная скрывает переменную класса
Хотя современные IDE легко обнаруживают такую ошибку, хотелось бы рассмотреть такую ошибку подробнее. Начнем с классического присвоения переменной в конструкторе. Пример правильный. Тут никакой ошибки нет.

Однако, что произойдет, если вы используете такой прием в методе, а не в конструкторе класса? В обычном методе использовать такой прием не рекомендуется. Вопрос относится к правильному проектированию класса.

Простое объяснение: В методе переменная с тем же именем, что и переменная класса, является локальной по отношению к методу. Вы можете обращаться к переменной класса используя this.val. Однако такое обращение из метода, при неправильном проектировании класса только вызовет побочные эффекты и может ухудшить читаемость кода.

Приведение типов в арифметических выражениях выполняется автоматически

Это может стать причиной досадных ошибок.

Одно из возможных решений при работе со строкой:

Еще одна ошибка приведена в следующем коде.

В данном случае получится бесконечный цикл.

Объяснение. Тип byte [-128, 127]. 128 уже не входит в этот диапазон. Происходит переполнение, и цикл повторяется. Необходимость использования byte в данном случае сомнительная. Хотя имеет место в редких случаях. Рекомендация — использовать int вместо byte. Другая рекомендация — не использовать цикл в вашем алгоритме.

Не проинициализированы объекты, являющиеся элементами массива

Correct way to compare floats or doubles in Java

Correctly compare float or compare double is not only Java specific problem. It can be observed in almost all the programming languages today. In computer memory, floats and doubles are stored using IEEE 754 standard format. How the actual storage and conversion works, it is out of scope of this article.

For now, just understand that during computations and conversions, minor rounding errors can be introduced in these numbers. That’s why it is not advisable to simply rely on the equality operators (==) to compare floating-point numbers.

Let’s learn how to compare float values in Java.

1. Compare double – Simple comparison [Not recommended]

First look at the simple comparison to understand what exactly is wrong with comparing double with == operator. In given program, I am creating same floating point number (i.e. 1.1 ) using two methods:

  1. Add .1 , 11 times.
  2. Multiply .1 to 11.

In theory, both operations should produce the number 1.1 . And when we compare the results of both methods, it should match.

Look at the both values printed in console. f1 is computed to 1.0999999999999999 . Its exactly the problem which rounding off causes internally. That’s why, floating point comparison with ‘==’ operator is not recommended.

2. Compare double – Threshold based comparison [Recommended]

Now when we know the problem with equality operator, lets solve it. Using programming, we cannot change the way these floating point numbers are stored or computed. So we have to adapt a solution where we agree that a determine the differences in both values which we can tolerate and still consider the numbers equal. This agreed upon difference in values is called the threshold or epsilon.

So now to use ‘threshold based floating point comparison‘, we can use the Math.abs() method to compute a difference between the two numbers and compare the difference to a threshold value.

3. Compare double – Compare with BigDecimal [Recommended]

In BigDecimal class, you can specify the rounding mode and exact precision which you want to use. Using the exact precision limit, rounding errors are mostly solved.

Best part is that BigDecimal numbers are immutable i.e. if you create a BigDecimal BD with value «1.23» , that object will remain «1.23» and can never be changed. This class provide many methods which can be used to do numerical operations on it’s value.

You can use it’s compareTo() method to compare to BigDecimal numbers. It ignore the scale while comparing.

Java program to compare double with BigDecimal class.

Now just to verify, let’s solve out original problem using BigDecimal class.

That’s all about comparing floating point numbers in java. Share your thoughts in comments section.

Как сравнить double java

Completing the CAPTCHA proves you are a human and gives you temporary access to the web property.

What can I do to prevent this in the future?

If you are on a personal connection, like at home, you can run an anti-virus scan on your device to make sure it is not infected with malware.

If you are at an office or shared network, you can ask the network administrator to run a scan across the network looking for misconfigured or infected devices.

Another way to prevent getting this page in the future is to use Privacy Pass. You may need to download version 2.0 now from the Chrome Web Store.

Cloudflare Ray ID: 71af0c863f848fe9 • Your IP : 82.102.23.104 • Performance & security by Cloudflare

Похожие статьи