二つのdatetime時刻をコンマ7桁単位で取得した時の関数での相違点
조회 수: 3 (최근 30일)
이전 댓글 표시
下記のようなdatetimeを設定し、時刻差を二通りの関数で取得しました
%年、月、日またぎの確認
TIME1=datetime(2017,1,1,0,0,0.0001000);
TIME2=datetime(2016,12,31,23,59,59.9999000);
%計算①
S1=posixtime(TIME1)-posixtime(TIME2);
S11=round(S1*(double(10000000)));
%計算②
S2=seconds(TIME1- TIME2);
S22=round(S2*(double(10000000)));
上記のコードの場合、計算①と②がそれぞれ下記のような結果となりました
--------------------------------------------------------
計算① S1= 2.002716e-04
0.1μsでの表示(7桁でまるめこみ)
計算① S11= 2003
--------------------------------------------------------
計算② S2= 2.000000e-04
0.1μsでの表示(7桁でまるめこみ)
計算② S22= 2000
なぜこのような結果になったのか、わかる方がいれば教えていただければと思います。
MATLABはR2020bを使用しています。
よろしくお願いいたします。
댓글 수: 0
채택된 답변
Atsushi Ueno
2021년 6월 3일
편집: Atsushi Ueno
2021년 6월 3일
>なぜこのような結果になったのか
誤差 - 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通りの方法で計算してみると、質問で問われているような桁落ちが発生しない事を確認しました。上記説明の通り、秒の上に乗っかる年月日時分の数値がゼロになり、秒の差分演算に十分な有効桁数を使える為です。
추가 답변 (1개)
Hiro Yoshino
2021년 6월 3일
コンピュータの中は2進数なので、表現できる数字とそうで無い数字があります。
表現不可能な場合は近似するわけですが、MATLABの標準の double 型は 8byte のメモリを必要とします。従って、数値を近似した際に、浮動小数点の仮数部に使うことができるbitサイズが大きいほど正確に近似できます。
つまり 52 bit が仮数部に用いられるわけですが、答えが同じになるべき計算でも、使っているbit によって答えが変わります。
a =(100000000000000+ 4/3) - (100000000000000+ 1)
b = 4/3 - 1
a == b
a と b は答えが一緒になるはずですが、4/3 の近似の良さが a, b で異なるため、答えが変わってきます。
上のコードでは、差分が同じになるはずですが、基準となる原点を posixtime は大幅にずらしており、それにより数値が大きくなっています。つまり近似の精度が下がっている状態だと考えられます。これが理由です。
참고 항목
카테고리
Help Center 및 File Exchange에서 Data Type Conversion에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!