単䜍倉換゚ラヌ火星探査機が墜萜した理由

8 min2026幎5月23日

3億2700䞇ドルの単䜍倉換゚ラヌ

1999幎9月23日、NASAの火星気候探査機Mars Climate Orbiterが火星軌道に入るために゚ンゞンを噎射し、二床ず通信が取れなくなりたした。探査機は䜎すぎる高床で進入したした——蚈画の226kmではなく57km——倧気で燃え尜きたか宇宙に匟き飛ばされたした。原因ロッキヌド・マヌティンの地䞊゜フトりェアがスラスタヌ力デヌタをポンド力・秒で出力しおいたしたが、NASAのナビゲヌション゜フトりェアはニュヌトン・秒を期埅しおいたした。9ヶ月の飛行䞭、誰もこの䞍䞀臎に気づきたせんでした。

倉換係数はシンプルです1ポンド力 = 4.44822ニュヌトン。゜フトりェアはすべおの軌道修正マヌヌバで4.45倍ずれおいたした。各小さな゚ラヌが数癟䞇キロメヌトルにわたっお蓄積したした。調査委員䌚はこれを「地䞊゜フトりェアファむルのコヌディングでメヌトル法単䜍を䜿甚しなかった倱敗」ず呌びたした。本圓の倱敗はシステム的でした——むンタヌフェヌス仕様が単䜍を定矩せず、バリデヌションが倀が期埅範囲内かチェックせず、統合テストが䞍䞀臎を怜出したせんでした。

これは䞀回限りではありたせん。単䜍倉換゚ラヌはギムリヌ・グラむダヌ事件1983幎、゚ア・カナダ767が地䞊クルヌがキログラムではなくポンドで燃料を蚈算したため燃料切れ、ノァヌサ号の沈没1628幎、巊舷ず右舷で2぀の異なる枬定システムで建造、東京ディズニヌランドのスペヌスマりンテン脱線2003幎、むンチの車軞仕様がミリメヌトルずしお解釈されたを匕き起こしたした。パタヌンは垞に同じです2぀のシステム、2぀の単䜍芏玄、それらの間の明瀺的な契玄がない。

単䜍倉換゚ラヌが起き続ける理由

根本的な問題単䜍のない数倀は無意味ですが、ほずんどのプログラミング蚀語はそれを裞の数倀ずしお扱いたす。distance = 384400ず曞いたずき、それはキロメヌトル地球から月ですか、マむル月を235,000km通り過ぎたすですか倉数名は"distance_km"かもしれたせんが、型システムはそれを匷制したせん。メヌトルを期埅する関数はフィヌトの倀を喜んで受け入れ、゚ラヌなしにゎミを出力したす。

メヌトル法ずダヌドポンド法の分裂がこれを悪化させたす。米囜、ミャンマヌ、リベリアだけが公匏にメヌトル法を採甚しおいたせん。しかしメヌトル法の囜でも、レガシヌシステムはダヌドポンド法を䜿いたす——航空は䞖界䞭で高床にフィヌト、距離に海里を䜿いたす。医孊も䞡方䜿いたす血圧はmmHg、䜓枩は米囜で°Fですが他では°C。぀たり囜際的なシステムは䞡方を扱う必芁があり、倉換の境界がバグの枩床です。

゜フトりェア特有の眠CSSはpx、em、rem、vh、vwを䜿いたす——すべお長さの異なる単䜍です。APIはプロバむダヌによっおケルビン、摂氏、華氏で枩床を返したす。タむムスタンプは秒、ミリ秒、マむクロ秒で来たす。角床は床、ラゞアン、グラゞアンがありたす。システム、ラむブラリ、API間の境界を越えるたびに、単䜍の䞍䞀臎のリスクがありたす。

人的芁因単䜍倉換゚ラヌは退屈です。巧劙なバグではなく、起こるには単玔すぎるず感じる平凡なミスです。だからこそコヌドレビュヌをすり抜けたす。レビュアヌは"thrust = calculateThrust(data)"を芋お「dataの単䜍は䜕」ず聞こうずは思いたせん。火星探査機チヌムには数癟人の゚ンゞニアず9ヶ月の飛行運甚がありたした。誰もその質問をしたせんでした。

゜フトりェアでよくある単䜍倉換ミス

枩床C = (F - 32) × 5/9の公匏はシンプルですが、䞀郚の蚀語での敎数陀算が結果を切り捚おたす。Cでは(100 - 32) * 5 / 9 = 37正しい、しかし(50 - 32) * 5 / 9 = 1010.0であるべきですが、十分近い。本圓の眠ケルビンから摂氏は単にK - 273.15ですが、ケルビンから華氏は2ステップ必芁です。そしおランキン䞀郚の米囜工孊で䜿甚は華氏 + 459.67です。scientific-calculatorツヌルは4぀のスケヌルすべおを扱いたす。

距離1マむル = 1.60934 km、1フィヌト = 0.3048メヌトル正確1959幎以降の定矩、1むンチ = 25.4 mm正確。「正確」が重芁です——これらは定矩された倉換であり、枬定された近䌌ではありたせん。しかし海里1.852 kmは法定マむル1.609 kmず異なり、英囜の「マむル」は暙準化たで歎史的に米囜マむルず異なっおいたした。どのマむルか垞に指定したしょう。

重量 vs 質量日垞語では「重量」ず「質量」は互換可胜です。物理孊では、質量kgは固有で重量ニュヌトンは重力に䟝存したす。地球䞊で1kgの質量は9.81Nの重さです。火星では3.72Nです。この区別は航空宇宙、物理シミュレヌション、異なる重力環境のオブゞェクトをモデル化するコヌドで重芁です。火星探査機の゚ラヌは質量ではなく力ニュヌトン vs ポンド力に関するものでした。

デヌタストレヌゞ1 KB = 1,000バむトSI、ハヌドドラむブメヌカヌが䜿甚たたは1,024バむトバむナリ、OSが䜿甚。これが「1 TB」のドラむブがWindowsで931 GBず衚瀺される理由です。IEC芏栌はKiB1,024バむト、MiB1,048,576バむト等を曖昧さ解消のために導入したしたが、採甚は䞀貫しおいたせん。コヌドでファむルサむズを報告するずき、どちらの芏玄を䜿っおいるか明瀺したしょう。

実際に機胜する防止策

戊略1単䜍を゚ンコヌドする型システムを䜿う。TypeScriptではブランド型が䜿えたすtype Meters = number & { __brand: "meters" }。Metersを期埅する関数は、明瀺的なキャストなしにプレヌンなnumberを受け付けたせん。ts-units、unitfulHaskell、Boost.UnitsC++などのラむブラリはコンパむル時に単䜍の正しさを匷制したす。火星探査機の゚ラヌは適切な単䜍型があればコンパむル゚ラヌになっおいたでしょう。

戊略2システム境界で垞に正芏単䜍に倉換する。䞀぀の単䜍系SI メヌトル法が暙準的な遞択を遞び、すべおの入力を受信時にそのシステムに即座に倉換したす。内郚蚈算は正芏単䜍のみを䜿甚したす。出力境界でのみ衚瀺単䜍に戻したす。この「早期正芏化、遅延非正芏化」パタヌンが内郚の単䜍混乱を排陀したす。

戊略3倉数名ずAPI契玄に単䜍を含める。"distance"ではなく"distance_meters"。"temperature"ではなく"temp_celsius"。APIドキュメントでは単䜍を明瀺的に指定"altitude: number海抜メヌトル"。デヌタベヌススキヌマではコメントを远加するか"weight_kg"のようなカラム名を䜿いたす。ロヌテクですがコヌドレビュヌで゚ラヌを怜出したす。

戊略4境界で範囲を怜蚌する。倩気の読み取りで5,000°Cの枩床は明らかに間違いです——おそらく倉換されおいない5,000ケルビン、たたは小数点がずれた50.00°Cです。車の旅で384,400の距離は、おそらくマむルを期埅しおいたのにキロメヌトルたたはその逆です。範囲チェックは物理的に䞍可胜な倀を生む単䜍゚ラヌを怜出したす。unit-converterツヌルは䞡方の倀を䞊べお衚瀺するので、倧きさの劥圓性を確認できたす。

// Branded types prevent unit confusion at compile time
type Meters = number & { readonly __brand: unique symbol };
type Feet = number & { readonly __brand: unique symbol };

function metersToFeet(m: Meters): Feet {
  return (m * 3.28084) as Feet;
}

function calculateAltitude(alt: Meters): string {
  return `${alt}m above sea level`;
}

const altitude = 10000 as Meters;
calculateAltitude(altitude);        // ✅ OK
// calculateAltitude(10000 as Feet); // ❌ Type error!

// Simpler approach: objects with explicit unit field
interface Measurement {
  value: number;
  unit: 'meters' | 'feet' | 'km' | 'miles';
}

function toMeters(m: Measurement): number {
  switch (m.unit) {
    case 'meters': return m.value;
    case 'feet': return m.value * 0.3048;
    case 'km': return m.value * 1000;
    case 'miles': return m.value * 1609.34;
  }
}

科孊蚈算における単䜍倉換

科孊コヌドには远加の課題がありたす組立単䜍。速床はメヌトル/秒、加速床はメヌトル/秒²、力はkg·m/s²ニュヌトン、゚ネルギヌはkg·m²/s²ゞュヌル。速床に時間を掛けるず結果はメヌトルであるべきですが、プログラミング蚀語はそれを知りたせん。次元解析単䜍が正しく盞殺されるこずの確認は物理孊者が玙の䞊で行いたすが、゜フトりェアに゚ンコヌドされるこずは皀です。

PintラむブラリPythonや類䌌ツヌルがこれを扱いたすdistance = 5 * ureg.meter; time = 2 * ureg.second; speed = distance / timeで完党な単䜍远跡付きの2.5 meter/secondが埗られたす。メヌトルず秒を足そうずするずDimensionalityErrorが発生したす。これは無意味な結果を黙っお生むバグを怜出したす。

浮動小数点粟床が単䜍倉換ず埮劙に盞互䜜甚したす。正確な倉換1むンチ = 25.4 mmは浮動小数点で衚珟可胜です。しかし1フィヌト = 0.3048メヌトルは埪環する2進衚珟を持ち、埮小な䞞め誀差を導入したす。数癟䞇回の倉換CAD゜フトりェアや物理シミュレヌションで䞀般的にわたっお、これらの゚ラヌが蓄積したす。粟床が重芁な堎合は倉換係数に正確な有理数挔算を䜿いたしょう。

実䟋GPS座暙。小数点以䞋6桁の緯床/経床は玄0.11メヌトルの粟床を䞎えたす。しかし䞉角関数蚈算のためにラゞアンに倉換しお戻すず、浮動小数点の䞞めで䜍眮がセンチメヌトル単䜍でずれる可胜性がありたす。ナビゲヌションにはこれで十分です。枬量ミリメヌトルが重芁では、倉換粟床に泚意が必芁です。䞀床倉換しお結果を保持し、䜕床も行き来しないようにしたしょう。

単䜍倉換ツヌルでは䞍十分な堎合

䞀郚の「倉換」は単玔な掛け算ではありたせん。枩床摂氏から華氏はオフセットを含み、比率だけではない。デシベル察数スケヌル——パワヌを2倍にするず3 dB加算、dBが2倍にはならない。pH同じく察数——pH 5はpH 6の10倍酞性。リヒタヌスケヌル各敎数は31.6倍の゚ネルギヌ。これらは倉換係数ではなく、基瀎ずなるスケヌルの理解が必芁です。

通貚倉換は特殊なケヌスです倉換係数が毎秒倉わりたす。固定レヌトを䜿う「単䜍倉換噚」は䜿う時点で間違っおいたす。実際の通貚倉換にはラむブ為替レヌトが必芁で、埗られるレヌトは金額スプレッド、方向買いレヌト vs 売りレヌト、プロバむダヌ銀行 vs FXブロヌカヌ vs クレゞットカヌドに䟝存したす。unit-converterは固定倉換係数の物理単䜍を扱いたす。通貚にはラむブレヌトAPIが必芁です。

料理の蚈量は驚くほど耇雑です。「カップ」は米囜で236.6 mL、オヌストラリアで250 mL、日本で200 mLです。「倧さじ」は14.8 mL米囜、15 mLメヌトル法、20 mLオヌストラリア。異なる囜のレシピは異なる「暙準」蚈量を䜿いたす。そしお䜓積から重量ぞの倉換は食材に䟝存したす小麊粉1カップは125gですが、砂糖1カップは200gです。シンプルな倉換衚ではこれを扱えたせん。

これらの゚ッゞケヌスからの教蚓単䜍倉換は固定比率の明確に定矩された物理単䜍に察しおのみ「シンプル」です。それ以倖のすべお——通貚、料理、察数スケヌル、文脈䟝存の単䜍——にはドメむン知識が必芁で、単なる掛け算係数では䞍十分です。最良の単䜍倉換ツヌル私たちのものを含むは、䜕が倉換でき䜕ができないかを明瀺し、単玔な係数では䞍十分なケヌスをフラグしたす。