Один из способов получить диапазон - использовать целые числа, масштабируя вероятность, скажем, на 10 100 . Для нижней границы всегда округлять в меньшую сторону, а для верхней границы всегда в большую:
>>> lower = 10**100
>>> for i in range(10**6):
lower = lower * (2**32 - i) // 2**32
>>> lower
27390147476140722271150280539996691121583143636646
>>> upper = 10**100
>>> for i in range(10**6):
upper = -(-upper * (2**32 - i) // 2**32)
>>> upper
27390147476140722271150280539996691121583143640960
Выравнивание:
upper 27390147476140722271150280539996691121583143640960
p 2.7390147476139603e-51
lower 27390147476140722271150280539996691121583143636646
Мы видим, что p
( float
) на самом деле выходит за пределы реального диапазона, слишком мало. Но его первые двенадцать цифр верны, так что это кажется довольно хорошим.
Сравнивая lower
и upper
, мы также получаем довольно много совпадающих и, следовательно, правильных цифр: 2,73901474761407222711502805399966911215831436e-51. А с большим коэффициентом масштабирования мы можем получить еще больше.