質問: 二つのdatetime時刻をコンマ7桁単位で取得した時の関数での相違点 下記のようなdatetimeを設定し、時刻差を二通りの関数で取得しました %年、月、日またぎの確認 time1=datetime(2017,1,1,0,0,0.0001000); time2=datetime(2016,12,31,23,59,59.9999000); %計算1 s1=posixtime(time1)-posixtime(time2); s11=round(s1*(double(10000000))); %計算2 s2=seconds(time1- time2); s22=round(s2*(double(10000000))); 上記のコードの場合、計算1と2がそれぞれ下記のような結果となりました -------------------------------------------------------- 計算1 s1= 2.002716e-04 0.1μsでの表示(7桁でまるめこみ) 計算1 s11= 2003 -------------------------------------------------------- 計算2 s2= 2.000000e-04 0.1μsでの表示(7桁でまるめこみ) 計算2 s22= 2000 なぜこのような結果になったのか、わかる方がいれば教えていただければと思います。 matlabはr2020bを使用しています。 よろしくお願いいたします。
回答: >なぜこのような結果になったのか 誤差 - wikipedia ->浮動小数点数間の減算において桁落ちが発生している為です。 一つの変数内で年,月,日,時,分,秒も計算する必要が有る方法と無い方法の2通りで差分0.0002秒を得ようとしている為です。 >> posixtime(time1) ans = 1.483228800000100e+09 >> posixtime(time2) ans = 1.483228799999900e+09 >> posixtime(time1)-posixtime(time2) ans = 2.002716064453125e-04 こちら側は、double型に年月日時分秒を含めた時刻の差を演算しています。0.0002秒の差分の「上側」に13桁もの情報が乗っていて、「下側」の計算に掛けられる有効桁数が少ないのです。double型の仮数部は 52 ビット、自由に動かせる10進の有効桁数は15桁です。その内13桁も「上側」の計算に取られ、「下側」の計算に使える有効桁数はわずか2桁です。それでも浮動小数点数の演算をすると、有効数字桁未満は意味のない(2進数で示せる)結果が出力されます。詳細は:浮動小数点数 - wikipedia >> time1.second ans = 1.000000000000000e-04 >> time2.second ans = 59.999899999999997 >> time1.second-(time2.second-60) ans = 2.000000000033197e-04 こちら側は、double型に秒のみを含めた時刻の差を演算しています。time1とtime2はdatetime型というクラスのオブジェクトで、内部に年月日時分秒のプロパティ値を持っています。time1-time2を演算するとこの内部プロパティ値間の演算が行われる為、seconds関数経由で秒同士の演算結果が得られます。こちらは十分な有効桁数があります。 time1=datetime(1970,1,1,0,0,0.0002000); time2=datetime(1970,1,1,0,0,0.0001000); 試しに上記の差分を2通りの方法で計算してみると、質問で問われているような桁落ちが発生しない事を確認しました。上記説明の通り、秒の上に乗っかる年月日時分の数値がゼロになり、秒の差分演算に十分な有効桁数を使える為です。