При подготовке ответа на Подсчитайте, сколько разных значений перечислит список в Mathematica. Я столкнулся с нестабильностью (из-за отсутствия лучшего термина) как в DeleteDuplicates
и Tally
, которые я не понимаю.
Рассмотрим сначала:
a = {2.2000000000000005, 2.2, 2.1999999999999999};
a // InputForm
[email protected] // InputForm
[email protected] // InputForm
[email protected] // InputForm
{2.2000000000000006`, 2.2, 2.1999999999999997`}
{2.2000000000000006`, 2.2, 2.1999999999999997`}
{2.1999999999999997`, 2.2, 2.2000000000000006`}
{{2.2000000000000006`, 3}}
Такое поведение, как я ожидал, в каждом случае. Tally
компенсирует незначительные числовые различия и видит, что каждый элемент эквивалентен. Union
и DeleteDuplicates
все элементы уникальны. (Это поведение Tally
не задокументировано, насколько я знаю, но я использовал его раньше.)
Теперь рассмотрим это осложнение:
a = {11/5, 2.2000000000000005, 2.2, 2.1999999999999997};
a // InputForm
[email protected] // InputForm
[email protected] // InputForm
[email protected] // InputForm
{11/5, 2.2000000000000006, 2.2, 2.1999999999999997}
{11/5, 2.2000000000000006, 2.2}
{2.1999999999999997, 2.2, 11/5, 2.2000000000000006}
{{11/5, 1}, {2.2000000000000006, 1}, {2.2, 2}}
Вывод Union
как ожидалось, но результаты как от DeleteDuplicates
, так и от Tally
являются неожиданными.
-
Почему
DeleteDuplicates
вдруг видит2.1999999999999997
как дубликат, который нужно устранить? -
Почему
Tally
внезапно видит2.2000000000000006
и2.2
как отличные, когда это не было раньше?
В качестве связанной точки видно, что упакованные массивы влияют на Tally
:
a = {2.2000000000000005, 2.2, 2.1999999999999999};
a // InputForm
[email protected] // InputForm
{2.2000000000000006, 2.2, 2.1999999999999997}
{{2.2000000000000006`, 3}}
a = Developer`[email protected];
a // InputForm
[email protected] // InputForm
{2.2000000000000006, 2.2, 2.1999999999999997}
{{2.2000000000000006`, 1}, {2.2, 2}}