7

私は次の手順を持っています:

procedure GetDegree(const num : DWORD ; var degree : DWORD ; min ,sec : Extended);
begin
  degree := num div (500*60*60);
  min := num div (500*60) - degree *60;
  sec := num/500 - min *60 - degree *60*60;
end;

次数変数が割り当てられると、デバッガーは手順の最後までスキップします。何故ですか?

4

1 に答える 1

17

それは最適化です。変数minsecは値によって渡されます。つまり、それらへの変更は呼び出し元には表示されず、この手順に限定されます。したがって、コンパイラは、それらに割り当てることが無意味であることを理解できます。変数に割り当てられた値を読み取ることはできません。したがって、コンパイラは時間を節約し、割り当てをスキップすることを選択します。私はあなたがこのような手順を宣言するつもりだったと思います:

procedure GetDegree(const num: DWORD; var degree: DWORD; var min, sec: Extended);

前の質問で言ったように、を使用する意味はあまりありませんExtendedSingle標準の浮動小数点型の1つ、またはを使用することをお勧めしますDouble。または、Realにマップするジェネリックを使用することもできますDouble

また、浮動小数点型であると宣言minしましたが、計算では整数が計算されます。あなたの前の質問に対する私の答えは、この点で非常に正確です。


これらの値を保持するレコードを作成することをお勧めします。3つの別々の変数を渡すと、関数のインターフェースが非常に乱雑になり、カプセル化が壊れます。これらの3つの値は、全体として考えた場合にのみ意味があります。

type
  TGlobalCoordinate = record
    Degrees: Integer;
    Minutes: Integer;
    Seconds: Real;
  end;

function LongLatToGlobalCoordinate(const LongLat: DWORD): TGlobalCoordinate;
begin
  Result.Degrees := LongLat div (500*60*60);
  Result.Minutes := LongLat div (500*60) - Result.Degrees*60;
  Result.Seconds := LongLat/500 - Result.Minutes*60 - Result.Degrees*60*60;
end;

function GlobalCoordinateToLongLat(const Coord: TGlobalCoordinate): DWORD;
begin
  Result := Round(500*(Coord.Seconds + Coord.Minutes*60 + Coord.Degrees*60*60));
end;
于 2012-05-23T18:52:31.193 に答える