在 664 位應用程式中,如果我將浮點常量與從 StrToFloat() 獲得的相同“值”的值進行比較,我會得到不同的結果。例如:
procedure foo;
const
d1 = 0.6694716
d3: double = 0.6694716
var
d2: double;
begin
d2 := StrToFloat('0.6694716');
if d1 = d2 then
beep;
if d1 = d3 then
beep;
if d2 = d3 then
beep;
end;
d1 和 d3 的十六進制值為 $B47339B4,而 d2 的十六進制值為 $B47339B3。雖然它們是“相等”的比較。它們在技術上并不相同。據我所知,常數 d1 和 d2 是錯誤的。也許編譯器使用 FPU,這是由于四舍五入?
沒有將我所有的常量都設為字串并在運行時轉換它們。任何人都知道解決這個問題?
uj5u.com熱心網友回復:
Delphi 中的浮點文字默認是擴展的。在 64 位中,這不應該有任何區別,但在 32 位中卻有。我的猜測是決議器仍然在內部將浮點文字表示為 10 位元組浮點(擴展),然后 64 位編譯器在編譯時將其“向下舍入”為 8 位元組(雙精度)。
如果我的假設是正確的,那么可能沒有任何辦法可以規避這一點。
編輯
Delphi 進行以下轉換
- 雙(3FE56C4FB47339B3)轉換為擴展(3FFEAB627DA399CD9800)
- 雙(3FE56C4FB47339B4)轉換為擴展(3FFEAB627DA399CDA000)
- 0.6694716 已擴展(3FFEAB627DA399CD9C00)
uj5u.com熱心網友回復:
令人惡心的是,我將 const 作為字串值,并在單元初始化中將它們轉換為 double。這樣我們就得到了雙重而不是擴展的數學。這似乎有效。我希望它不適用于 32 位。
function HexToDouble(const val: uint64): double; inline;
begin
result := Pdouble(@val)^;
end;
//use
D1 := HexToDouble($3fe56c4fb47339b3);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/435799.html
標籤:德尔福
