Поэтому я хочу создать набор чисел с плавающей запятой, где два числа считаются равными при определенном допуске. Например, если у меня есть набор
a = set([1, 2, 3])
если я добавлю элемент 1.00001 с допуском 1e-4, результирующий набор должен быть
{1, 2, 3}
и не
{1, 1.00001, 2, 3}
Мы можем использовать круглую функцию для проверки tolerance of 1e-4
a = set([1,2,3])
def add(number):
if(round(number,4) not in a):
a.add(number)
add(1)
print(a)
add(1.0000)
print(a)
add(1.0001)
print(a)
add(1.1)
print(a)
Мне кажется, вы должны просто проверить каждый элемент уже в наборе, и если абсолютная разница между этим элементом и тем, который вы пытаетесь добавить, меньше порога, просто не добавляйте его.
Что-то вроде этого должно сделать трюк:
def AddToSetWithThreshold(pSet, pValue, pThreshold):
vList = [entry for entry in pSet if abs(pValue - entry) < pThreshold]
if len(vList) == 0:
pSet.add(pValue)
a = set([1, 2, 3]) ; print(a)
AddToSetWithThreshold(a, 1.00001, 1e-4) ; print(a)
AddToSetWithThreshold(a, 1.00001, 1e-6) ; print(a)
Поскольку первое добавление слишком близко к 1
а второе - нет, это приведет к следующему результату:
set([1, 2, 3])
set([1, 2, 3])
set([1, 2, 3, 1.00001])
импортировать математику и использовать ceil
import math
decimals = 3
v = 1.234566789
print(math.ceil(v*pow(10,decimals))/pow(10,decimals))
# 1.234
или если вы хотите, чтобы intger как "порог" просто использовал
print(float(int(v)))
# 1.0
round
.
__hash__
.a
иc
могут быть достаточно далеко друг от друга, чтобы они не считались «равными», но были достаточно близки, чтобыb
можно было считать равным любому из них. Добавление одинаковых номеров к наборам в разных порядках может привести к разным результатам. Математически отношение эквивалентности должно быть транзитивным и нарушать его, что приведет к плохому поведению. Создание подобных кладж для чисел с плавающей запятой, как правило, плохой дизайн.