
doubleの精度でmmは守れるか — 座標計算と浮動小数点
座標変換のような数値計算をアプリで実装するとき、意外と見落とされがちなのが「その精度、浮動小数点で本当に守れているか」という問題です。GeoConverterPro(GCVP)はmm単位の精度を目標にしていますが、これは「計算式が正しい」だけでは達成できず、倍精度浮動小数点(double)がどこまで桁を保証できるかを理解した実装が必要です。今回は座標計算における浮動小数点の精度設計を整理します。
doubleの有効桁数はおよそ15〜17桁
IEEE754の倍精度浮動小数点(double、64bit)は、仮数部52bitで数値を表現します。これは10進数に換算すると、およそ15〜17桁の有効桁数に相当します。一般的なプログラミング言語(Swift・C#・Pythonなど)のDouble型はこの仕様に準拠しており、GeoCoreJPの内部計算もdoubleを基本としています。
15〜17桁と聞くと十分に思えますが、これは「有効桁数」であって「小数点以下の桁数」ではない点に注意が必要です。整数部の桁数が増えるほど、小数点以下に使える桁数は目減りします。
緯度経度でmm精度を出すには何桁必要か
緯度・経度「1度」は何メートルかで扱ったとおり、緯度1度はおよそ111kmです。この換算をもとに、必要な小数点以下の桁数を逆算すると次のようになります。
| 小数点以下 | 緯度での距離の目安 |
|---|---|
| 0.0001度 | 約11m |
| 0.00001度 | 約1.1m |
| 0.000001度 | 約11cm |
| 0.0000001度 | 約1.1cm |
| 0.00000001度 | 約1.1mm |
つまり、mm精度を出すには小数第8位まで必要になります。緯度の整数部は2桁(日本付近は北緯20〜46度)なので、「35.65831234」のような値は整数部2桁+小数部8桁=合計10桁程度です。doubleの15〜17桁からすればまだ余裕がありますが、後述する計算過程での桁の消費を考えると、無限に余裕があるわけではありません。
危ないのは「値そのもの」より「計算の途中」
doubleの桁数だけを見れば、緯度経度の入出力は問題なく収まります。精度が本当に危なくなるのは、計算の途中経過です。代表的な落とし穴は次の3つです。
1. 近い大きな数どうしの引き算(桁落ち)
地心直交座標(ECEF・XYZ)は地球中心からの距離で、値そのものが約637万m(6,378,137m前後)という大きな数になります。2点間の変位(数mm〜数m)を求めるためにこの大きな数どうしを引き算すると、上位の桁が打ち消し合って有効桁が大きく失われる「桁落ち(catastrophic cancellation)」が起きます。対策としては、可能な限り局所原点(現場付近の代表点)を基準にした相対座標に変換してから差分計算を行うことが有効です。
2. 度⇄ラジアン往復での誤差蓄積
三角関数はラジアン単位を前提とするため、度→ラジアン→度という変換を何度も繰り返す実装では、そのたびに丸め誤差がわずかに蓄積します。1回あたりの誤差は無視できるレベルでも、往復変換の反復計算のようにNewton-Raphson法で何十回も繰り返す処理では、収束判定のしきい値をdoubleの丸め誤差より十分大きく設定しないと、理論上は収束するはずの計算が振動して収束しない事態になり得ます。

3. 平面座標のスケール設計
平面直角座標系(X・Y)の値は、系の原点からの距離次第で数万〜数十万m規模になります。ここにmm単位の精度を求める場合も、整数部の桁数と小数部の桁数の合計がdoubleの有効桁数に収まっているかを意識する必要があります。国土地理院の平面直角座標系(1〜19系)は原点を都道府県単位で分散させているため、UTMのような広域グリッドに比べて座標値が小さく収まりやすく、この観点でも精度確保に有利な設計だと言えます。
floatを使ってはいけない理由
単精度浮動小数点(float、32bit)は仮数部23bitで、有効桁数はおよそ7桁しかありません。緯度経度の整数部だけで2〜3桁を使うことを考えると、floatでは小数点以下4〜5桁程度しか確保できず、m単位の精度すら怪しくなります。座標変換・測量計算では、精度を犠牲にしてまでfloatのメモリ効率を選ぶ理由はほとんどありません。GeoCoreJPでは座標値・パラメータ値ともにdoubleで一貫して扱っています。
精度を守るための実装指針
これまでの内容をまとめると、mm精度を守るための実装指針は次のようになります。
- 座標計算はdoubleで統一し、floatを混在させない
- 大きな絶対値どうしの差分計算は避け、局所原点を基準にした相対座標に変換してから行う
- 反復計算の収束判定しきい値は、doubleの丸め誤差より十分大きい値(例:0.1mm相当)に設定する
- 度⇄ラジアン変換は計算経路の中で最小限の回数に抑える
- 実装後は国土地理院の公式ツールとの全数検証や、検証値ドリブンの単体テストで、理論上の精度が実際に出ているかを確認する
「計算式が正しいこと」と「実装がその精度を実際に出せること」は別の問題です。特に測地計算のように多段階の変換を積み重ねる処理では、後者の検証を省略しないことが、mm精度を謳うアプリの信頼性を支えています。
まとめ
- IEEE754倍精度浮動小数点(double)の有効桁数はおよそ15〜17桁で、緯度経度でmm精度を出すには小数第8位までの桁が必要
- 精度が危なくなるのは値そのものよりも計算の途中経過(大きな数の引き算・角度変換の往復・座標のスケール)
- floatは有効桁数がおよそ7桁しかなく、座標変換の精度要求には不十分
- 理論上の精度が出ているかは、公式ツールとの比較や検証値ドリブンのテストで確認する必要がある
関連記事
- 緯度・経度「1度」は何メートル?(GeoPrism JP)
- 「逆変換の式」は存在しない — Newton-Raphson反復法を数式で理解する(GeoConverterPro)
- C#で測地計算の単体テストを書く — 検証値ドリブン開発(GeoDiveExa)
- GeoConverterProの座標変換を国土地理院の公式ツールで全数検証する(GeoConverterPro)
開発者より: アプリ・Kindle本・オープンソースの一覧は GitHub: amru195704 にまとめています。
お願い
本記事の情報は参考目的で掲載しており、正確性・完全性を保証するものではありません。誤記・不正確な情報がございましたら、コメント欄よりご指摘いただければ、確認のうえ修正いたします。
アプリを入手(App Store):GeoConverterPro(座標変換) | GeoPrism JP(測地系の可視化・学習)
コメントを残す