Лучший способ ответить на ваш вопрос - запустить тесты (как случайно распределенные, так и на основе диапазона?) И посмотреть, отличаются ли результирующие числа вообще в двоичном представлении.
Обратите внимание, что одна проблема, с которой вы столкнетесь, заключается в том, что ваши функции не будут работать со значением > MAX_INT/2
из-за способа, которым вы кодируете среднее значение.
avg = (x1+x2)/2 # clobbers numbers > MAX_INT/2
avg = 0.5*x1 + 0.5*x2 # no clobbering
Это почти наверняка не проблема, если только вы не пишете библиотеку уровня языка. А если большинство ваших чисел маленькие, это может вообще не иметь значения? На самом деле, это, вероятно, не стоит рассматривать, так как значение дисперсии будет превышать MAX_INT
, поскольку это по сути квадратная величина; Я бы сказал, что вы можете использовать стандартное отклонение, но никто этого не делает.
Здесь я делаю некоторые эксперименты на python (которые, я думаю, поддерживают IEEE, что бы это ни было, в силу вероятности делегирования математики библиотекам C ...):
>>> def compare(numer, denom):
... assert ((numer/denom)*2).hex()==((2*numer)/denom).hex()
>>> [compare(a,b) for a,b in product(range(1,100),range(1,100))]
Нет проблем, я думаю, потому что деление и умножение на 2 хорошо представимо в двоичном виде. Однако попробуйте умножение и деление на 3:
>>> def compare(numer, denom):
... assert ((numer/denom)*3).hex()==((3*numer)/denom).hex(), '...'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
File "<stdin>", line 2, in compare
AssertionError: 0x1.3333333333334p-1!=0x1.3333333333333p-1
Возможно, это имеет большое значение? Возможно, если вы работаете с очень маленькими числами (в этом случае вы можете использовать логарифмическая арифметика ). Однако, если вы работаете с большими числами (редко по вероятности) и задерживаете деление, вы, как я уже упоминал, будете переполнены рисками, но, что еще хуже, рискует ошибками из-за трудно читаемого кода .