Arduino로 원주율을 계산하다

12752 단어 Arduino원주율
나는 원주율을 계산하고 싶다!
수학을 좋아하는 사람이라면 한 번 생각할 수도 있어요.
적어도 나는 이렇게 생각한다.
이번에는 누구나 쉽게 구할 수 있는 아두노로 원주율의 근사치를 계산해보도록 하겠습니다.
한마디로 원주율의 계산 방법도 많다.그중에서도 이번에는 몬테카로법을 사용했다.
몬테카로법
인용자 itmedia.co.jp
몬테카로 방법은 확정된 값이 여러 확률 변수의 함수(수치모델)로 표시될 수 있을 때 무작위 수를 이용하여 각 변수가 가정한 확률 분포를 따라 대량의 샘플 값을 생성하고 여러 번 계산을 시도하여 결과에서 값을 얻는 분포 방법이다.
어떻게 된 거야?
간단하게 말하면 몇 개의 무작위 수를 반복해서 사용하여 계산하는 것이다.잘못하면 못 맞춰요.
몬테카로 방법을 사용하여 원주율(근사치)을 계산하는 것은 매우 유명하다.대부분의 사람들이 아래의 그림을 본 것 같아요.

이런 느낌으로 단위의 원 바깥쪽과 연결된 정사각형에 무작위로 점을 그려서 원의 내부인지 외부인지 판별하고 그것들의 비율에 따라 원주율의 근사치를 얻는다.그러니까
왜 그럴까요? 단위 원의 면적, 즉 반경이 1인 원의 면적은 S=pi*r^2의π보다 딱 맞습니다.또 정사각형의 면적은 4이다.
π/4를 확정한 후 원의 내부에 점을 그리는 것이다.
그래서 π ≒ (4 * 円の内部にある点の数)/(すべての点の数)살 수 있어요.
원의 내부인지 외부인지 원의 공식으로 점의 좌표를 대입하면 알 수 있다
상기 내용에 근거하여 프로그램을 편성하였다
계산 프로그램
다음은 이번에 사용한 프로그램입니다.
piCulculator.ino
#define SW 3
#define seedVolume 100000000

uint64_t inCirclePoints = 0;
uint64_t Step = 0;
void setup() {
  Serial.begin(115200);
  pinMode(SW, INPUT_PULLUP);
}

void loop() {
  byte swStatus0 = digitalRead(SW);
  if(swStatus0 == 0){
    Pi_Calculator(seedVolume);
  }
  delay(250);
}

void Pi_Calculator(uint64_t turn){
  Serial.print("Start Calculating ");
  Serial.print(turn);
  Serial.println(" Times...");
  for(uint64_t i = 0; i < turn; i++){
    float pointX = random(-32767, 32767) / 32767.0;
    float pointY = random(-32767, 32767) / 32767.0;

    if((pow(pointX, 2) + pow(pointY, 2)) <= 1.0){    //20220113, 変更しました:
      inCirclePoints++;
    }
    Step++;
  }
  float result = float(inCirclePoints * 4) / float(Step);
  Serial.println("Calculate Finished.");
  Serial.print("Result:");
  Serial.println(result, 10);
}
변수 유형을 잘못하지 않도록 주의하십시오
나는 변수의 유형이 틀렸다는 것을 알아차리지 못해서π=4.00의 출력에 대해 줄곧 괴로워했다
그나저나 3번 바늘에 연결된 버튼을 누르면 계산을 시작합니다.
2022-01-13 보완, 업데이트
루트 계산이 필요 없다는 걸 알고 삭제했어요.조금 고속화됐을 거예요.
또한 사용pow() 함수로 변경되었습니다.연산 속도에 대한 영향은 아직 명확하지 않지만, 그 중에서 검증을 진행할 것이다
추기는 여기까지다
코드 설명(변수 편)
전역 함수는 이 두 개다.
uint64_t inCirclePoints = 0;
uint64_t Step = 0;
위에서
- 원에 저장된 점의 수에 대한 변수
- 모든 점의 수량을 저장하는 변수
네.
로컬 변수의 코드 해석
코드 해설
일단 setup 함수.
void setup() {
  Serial.begin(115200);
  pinMode(SW, INPUT_PULLUP);
}
115220bps 직렬 통신으로 SW 트랙을 입력하고 내부 당김 저항을 사용합니다.
다음은 loop 함수입니다.
void loop() {
  byte sw = digitalRead(SW);
  if(sw == 0){
    Pi_Calculator(10000000);
  }
}
sw byte 선언 변수로 SW 힌트 상태 저장
다음 조건 지점에서 sw == 0 즉 버튼을 눌렀을 때Pi_Calculator(10000000); 호출 함수, 주요 계산을 하는 함수를 호출하여 매개 변수에 건네준다
uint 16 매개변수T형 범위 안에서는 뭐든지 다 돼요.
마지막 PiCalculator 함수
void Pi_Calculator(uint16_t turn){
  Serial.print("Start Calculating ");
  Serial.print(turn);
  Serial.println(" Times...");
  for(uint64_t i = 0; i <= turn; i++){
    float pointX = random(-32767, 32767) / 32767.0;
    float pointY = random(-32767, 32767) / 32767.0;
    if((pow(pointX, 2) + pow(pointY, 2) <= 1.0){
      inCirclePoints++;
    }
    Step++;
  }
  float result = float(inCirclePoints * 4) / float(Step);
  Serial.println("Calculate Finished.");
  Serial.print("Result:");
  Serial.println(result, 10);
}
위 세 개는 계산을 시작하는 통지입니다.
for 문장에서 실제 계산을 진행하다.이때 순환 횟수는 함수에 전달되는 수치이어야 한다
flat~어느 곳에서 x, y축 좌표를 무작위로 생성하고 원의 공식으로 대입하여 원점의 거리를 구한다R.만약 이것이 1 이하inCirclePoints에 1을 더한다면.turn 이 조작을 반복한 후 얻은 값에 근거하여 계산result.나는 그것을 직렬 모니터에 표시했다.그런 흐름입니다.
먼저 성우 연산자로 부점형을 강제로 계산하다
이 코드는 1000만 번은 들어가지만 시간이 많이 걸리기 때문에 두 자리 수를 줄여서 시행하는 게 좋을 것 같아요.void부분을float로바꾸고return result;까지 더하면계산결과를돌려줄 수도 있어요.
실제 가동의 결과
잠을 잘 때 실행해 봤어요.결과는 다음과 같다.
Result:3.1416676044
Result:3.1415107250
Result:3.1413543224
Result:3.1415123939
Result:3.1414935588
Result:3.1415750980
Result:3.1416082382
Result:3.1417074203
Result:3.1417162418
Result:3.1416881084
Result:3.1416106224
Result:3.1416251659
소수점 이하 3~4자리의 정확성.원래 높은 정밀도가 없는 아두노의 랜덤수를 사용했다면 더 좋았을 텐데.

좋은 웹페이지 즐겨찾기