Пятнично-тринадцатеричное

«И сделал литое из меди море – от края его до края его десять локтей – совсем круглое, высотой в пять локтей, и шнурок в тридцать локтей обнимал его кругом»
(3-я Царств 7:23)

В эпиграфе приведён текст из Священного писания, из которого прямо следует, что отношение длины окружности к её диаметру, также известное, как «число π» равно точно трём. Надеюсь, никто из присутствующих не намерен подвергать сомнению истинность священных текстов? Домыслы же еретиков и отступников про какую-то там иррациональность, есть не что иное, как гнусное фарисейство и сатанинская ересь, ожидающие Суда Святой Инквизиции.

Однако, поскольку эта ересь получила весьма широкое распространение, я решил развеять её в прах прямым расчётом этого проклятого числа. Просто посчитать его в лоб, чтобы уж ни у кого не оставалось никаких сомнений.

Таким образом, цель настоящего исследования – посрамить фарисеев и отступников и, в меру моих скромных сил, укрепить и возвысить сияющую истинность Священного Писания. Конечно же, она (истинность) настолько абсолютна и бесспорна, что не нуждается ни в каких моих «подтверждениях»! Зато я остро нуждаюсь в том, чтобы служить ей, всемерно благословлять её, и разбивать в пух и прах любые еретические, псевдонаучные построения. Чем я сейчас, помолясь, и займусь.

Итак, число π мы будем считать методом Монте-Карло (ну, а каким ещё способом его можно считать в пятницу, тринадцатого числа?).

Суть метода, для тех, кто с ним незнаком, такова:

Нарисуем в координатных осях единичный квадрат (на рисунке – пунктиром) и нарисуем четверть круга с радиусом равным единице и центром в начале координат (на рисунке – закрашен серым).
image
Очевидно, что площадь единичного квадрата равна единице, а площадь четверти круга единичного радиуса равна π/4. Тогда, если мы «набросаем» в этот квадрат достаточно много случайных точек, то отношение количества точек, попавших внутрь круга, к общему количеству «набросанных» точек будет приблизительно равно π/4. Причем, это будет тем точнее, чем больше случайных точек мы туда набросаем.
Собственно всё, осталось умножить полученную величину на 4 и получим приближение числа π, тем более точное, чем больше точек мы туда «набросали».

Нам потребуется функция для генерации псевдослучайных координат точек в диапазоне от 0 до 1. Ничего особенного, вот она:

Реализация
static inline double rndXY(void) {
	constexpr long lMax = 1000000;
	constexpr double dMax = lMax;
	return random(lMax) / dMax;
}

Также, нам потребуется функция для проверки попала точка с заданными координатами внутрь круга или не попала. Опять же, ничего особенного, просто по двум координатам, которые являются катетами прямоугольного треугольника, считаем гипотенузу (по теореме Пифагора). Если гипотенуза меньше единицы, то точка попала в круг, иначе - не попала.

Реализация
bool check(const double x, const double y) {
	return x * x + y * y < 1;
}

Ну и собираем всё вместе.

Полный код
//
// Возвращает true, если точка (x,y) попадает 
// внутрь единичной окружности и fals в противном случае
//
bool check(const double x, const double y) {
	return x * x + y * y < 1;
}

//
//	Генерирует псевдослучайное число от 0 до 1
//	с шестью разумными знаками после запятой
//
static inline double rndXY(void) {
	constexpr long lMax = 1000000;
	constexpr double dMax = lMax;
	return random(lMax) / dMax;
}


void setup(void) {
	Serial.begin(9600);
	//
	// Проводим totalTests проб, попадает ли случайная точка
	//	внутрь единичной окружности и сохраняем количество попаданий 
	//	в переменной col
	//
	constexpr int totalTests = 10000; // хватит. можно и больше
	long col=0;
	for (int i=0; i < totalTests; col+=check(rndXY(),rndXY()),i++);
	//
	// Считаем и печатаем число ПИ
	// Не забываем, что оно с плавающей точкой!
	//
	const double thePi = 4 * col / totalTests;
	Serial.print("PI = ");
	Serial.println(thePi);
}

void loop(void) {}

Запускаем и получаем результат

PI = 3.00

что, собственно, и требовалось доказать!

Всех с пятницей - 13-ым!

1 лайк

а ежели так:

Всеми “любимые” неявные преобразования. :slightly_smiling_face:

всё таки такие вещи надо подтверждать на кубитах, ИМХО

PS

Вообще интересно, что означает выражение “обнимать кругом”.
Если скажем, шнурок не сходится на какие-то доли процента, это уже “обнимать кругом” или еще нет.
Ежели шнурок должен сходиться (т.е. конец должен касаться начала), то возникают следующие соображения:

  1. “море” - это по идее впадина.
  2. Впадину можно “обнять” только изнутри (т.е. окружность “моря” проходит не по середине, а по внешней границе шнурка).
  3. Очевидно, шнурок должен иметь какую-то толщину.

Вопрос: какова толщина этого шнурка?

это ты о чём?

1 лайк

Тогда уж лучше с явным преобразованием. Вот так, например :slight_smile:

const double thePi = static_cast<double>(4 * col / totalTests);

издеваетесь? :slight_smile:

Почему, явное преобразование - оно ж всегда лучше неявного :slight_smile:

Или вы троллите, или я вконец чего-то не понимаюю Результат-то разный!
Вот так будет целочисленное деление

а вот так - “вещественное”

Ну? И в результате получаете неправильный результат! Или Вы решили с Библией поспорить? :slight_smile:

1 лайк

точно!
а я то думал…

не измышляй гипотез, -
“… море лежало на них, и зады их обращены были внутрь под него.

1 лайк

+100500!

Сразу видно серьёзного человека! Ознакомился с первоисточником и не выдумывает отсебятины! :slight_smile:

1 лайк