Усреднение чисел определенного числового типа безопасным способом, в то же время используя только этот числовой тип, действительно возможно, хотя я бы посоветовал использовать помощь BigInteger в практической реализации.Я создал проект для Безопасных числовых вычислений , который имеет небольшую структуру (Int32WithBoundedRollover), которая может суммировать до 2 ^ 32 int32 без каких-либо переполнений (структура внутренне использует два поля int32 для этого, поэтому больших данных нет.используются типы).
Когда у вас есть эта сумма, вам нужно вычислить сумму / сумму, чтобы получить среднее значение, которое вы можете сделать (хотя я бы не рекомендовал это), создав, а затем увеличивая на другое значение.экземпляр Int32WithBoundedRollover.После каждого приращения вы можете сравнивать ее с суммой, пока не найдете целую часть среднего.Оттуда вы можете снять остаток и рассчитать дробную часть.Вероятно, есть некоторые хитрые уловки, чтобы сделать это более эффективным, но эта базовая стратегия, безусловно, будет работать без необходимости прибегать к большему типу данных.
При этом текущая реализация не предназначена для этого (дляНапример, в Int32WithBoundedRollover нет оператора сравнения, хотя добавить его будет несложно).Причина в том, что в конце гораздо проще использовать BigInteger для выполнения вычислений.С точки зрения производительности это не имеет большого значения для больших средних, так как это будет сделано только один раз, и слишком просто и легко понять, чтобы беспокоиться о том, чтобы придумать что-нибудь умное (по крайней мере, пока ...).
Что касается вашего первоначального вопроса, касающегося длинного типа данных, Int32WithBoundedRollover можно преобразовать в LongWithBoundedRollover, просто поменяв местами ссылки int32 для длинных ссылок, и он должен работать точно так же.Для Int32s я заметил довольно большую разницу в производительности (на случай, если это будет интересно).По сравнению с методом BigInteger, который я создал, он на 80% быстрее для больших (как и в общем количестве точек данных) выборок, которые я тестировал (код для этого включен в модульные тесты для класса Int32WithBoundedRollover).Это, вероятно, в основном из-за разницы между операциями int32, выполняемыми аппаратно, а не программно, как операции BigInteger.