werry-chanの日記.料理とエンジニアリング

料理!コーディング!研究!日常!飯!うんち!睡眠!人間の全て!

C++で地球が何周まわった時かを導出するぞ

クソガキ「何時何分何秒地球が何周まわったとき〜?」

クソガキですね.

僕もクソガキだったので100万回くらい言ってました.

さて,そんなクソガキに出逢ってしまったあなたへ

ガチレスを食らわせてやりましょう.

werry-chan.hatenablog.com

このページでは,現在の時刻における地球が何周まわった時かを表示しています.

クソガキをこれで黙らせてやりましょう.



それでは,地球が何周まわった時かの導出方法を考えていきましょう.

まずは,地球年齢について調べます.

地球年齢は,粒子(原子)の放射年代測定によって45億4000万年(±1%)とされています.
地球の年齢 - Wikipedia

この地球年齢45億4000万 年は,地球誕生から西暦0 年までと考えます.

また注意する点として,地球年齢45億4000万 年は現代の測定方法で計算された時間という点です.

現在の地球自転は24 時間で1 周まわっていますが,地球誕生時の自転は5 時間で1 周です.

すなわち,地球誕生時の1 年は現代の\frac{5}{24} 年であるということです.

ここで地球自転の変化する1 年と現代の1 年をきちんと分けて考えましょう.

地球自転の変化する1 年を地球年,現代の1 年を現代年とします.

この現代年(1 日が24 時間,1 現代年は365.2422 日)を基準として計算をします.

地球誕生時(1 日が5 時間)から西暦0年(1 日が24 時間)までをN 地球年として,自転速度の変化が一定であると考えます.

そうすると,\Delta = \frac{24-5}{24N} 現代年ずつ1 年の長さが変化します.

すなわち,

\sum_{n=1}^{N} (\frac{5}{24} + \Delta (n-1)) \leq 4,540,000,000

\frac{5}{24}N + \frac{24-5}{24N} \frac{(N-1)N}{2} \leq 4,540,000,000

上式を満たす最大のNを求めることで,地球誕生から西暦0年までのN 地球年を求めることが可能です.

それでは二分探索で求めてみましょう.

#include <iostream>


using namespace std;
typedef long long ll;

int main(){
  ll birth = 45LL * 10000LL * 10000LL + 4000LL*10000LL;
  double sy = 5.0/24.0;
  double delta = 1.0-sy;
  ll left = 1, right = 1e15, middle;
  while(left+1 < right){
    middle = (right+left)/2;
    double year = sy*(middle)+delta/2*(middle-1);
    if(year > birth){
      right = middle;
    }
    else{
      left = middle;
    }
    cout << "now middle is " << middle << ", year is " << year << ", birth is " << birth << endl;
  }
  ll rotation = (middle+1)*365.2422;
  cout << rotation/10000/10000 << "億" << (rotation-(rotation/10000/10000)*10000*10000)/10000 << "万回" << endl;
  cout << rotation << endl;
  return 0;
}

これを実行すると,N = 約75億1448万と導け,地球が約2兆7446億621万回まわった時と導出されます.

そして,(西暦m年までの日数) = m \times 365.2422を追加します.

さらに暦上の2月は28日,その他の偶数月は30日,奇数月を31日として場合分けして,月による日数を計算して追加します.

最後に小数点以下を切り捨てて,地球の回った回数が導けます.


HP上では,javascriptc++の計算結果を使って以下のようにして表示します.

<span id="view_time"></span>
        <script>
            document.getElementById("view_time").innerHTML = getNow();
            function getNow() {
                var now = new Date();
                var year = now.getFullYear();
                var mon = now.getMonth()+1; //1を足すこと
                var day = now.getDate();
                var hour = now.getHours();
                var min = now.getMinutes();
                var sec = now.getSeconds();
                var rotation = 6215489 + year*365.2422;
                if (mon == 1){
                    rotation += day;
                }
                else if (mon == 2){
                    rotation += 31+day;
                }
                else if (mon%2 == 0){
                    rotation += 31+28+(mon-2)*30+(mon-2)/2;
                }
                else{
                    rotation += 31+28+(mon-2)*30+(mon-1)/2;
                }

                //出力用
                var s = year + "年" + mon + "月" + day + "日" + hour + "時" + min + "分" + sec + "秒, " + "地球が2兆7446億"+ Math.floor(rotation/10000) + "万" +  Math.floor(rotation-Math.floor(rotation/10000)*10000) + "回まわった時です."; 
                return s;
            }
        </script>

http://www.shurey.com/js/samples/2_msg10.html
このサイトを参考にjavascriptで時間取得をしました.

間違っているとか,改善点がありましたら教えてもらえると幸いです.