2014-04-28 68 views
1

我使用Delphi RAD Studio 2010和DecimalRounding_JH1.pas從http://cc.embarcadero.com/item/21909小數舍入和打印機選擇

它工作的很好,但我不知道爲什麼,在某些舊機器(帶有Windows XP SP3的Pentium IV)中,訪問printer.printerindex後回合失敗。我已經檢查過,問題不在於Windows XP,因爲它可以在具有此操作系統的其他機器上運行。

我做了一個簡單的項目,用DecimalRounding_JH1(drHalfUp)和兩位小數(1.105 - > rounds to 1.11)將一個擴展值四捨五入。但如果我讀取printer.printerindex,則1.105到1.10)。

我認爲這可能是「FDIV錯誤」,但編譯「FDIV安全」不能解決問題。

代碼:

var d1,d2:extended; 
    i:integer; 
begin 
    d1:=1.105; 
    d2:=DecimalRounding_JH1.DecimalRoundExt(d1,2,drHalfUp); 
    memo1.lines.add(FloatToStr(d2)); // --> shows 1.11 (OK) 
    i:=Printer.printerindex; 
    d2:=DecimalRounding_JH1.DecimalRoundExt(d1,2,drHalfUp); 
    memo1.lines.add(FloatToStr(d2)); // --> shows 1.10 (ERROR!!!) 
    ... 

我知道,這是很奇怪,但我測試過它,這就像我說的。 我能做什麼?

編輯: 如果我在i:=Printer.printerindex;之前加上Printer.printerindex:=1;(例如),那麼它再次有效。閱讀打印機單元,不同的是有關執行「SetToDefaultPrinter」與否:

function TPrinter.GetPrinterIndex: Integer; 
begin 
    if FPrinterIndex = -1 then SetToDefaultPrinter; 
    Result := FPrinterIndex; 
end; 

在此先感謝。

+0

FDIV錯誤影響了原來的奔騰。你沒有跑到我能向你保證的那些人身上。同樣值得指出的是,問題中的代碼有些缺陷。值'1.105'不能用二進制浮點表示。看看這裏看看最接近的精確浮點值:http://pages.cs.wisc.edu/~rkennedy/exact-float?number=1.105最後,我不知道你爲什麼使用擴展。它的性能很差,只存在於x86上。 –

+0

感謝您的幫助,但我有點絕望,我嘗試了一切,儘管我知道FDIV是舊奔騰中的一個bug。代碼(使用1.105)就是一個例子,但正如我所說的,在Printer.printerindex之後它並不好。但David Heffernan的解決方案一切都可以。謝謝。 – briast

回答

3

系統打印機庫的某些部分有修改8087控制字的相當惡劣的習慣。在使用Printer的方法和屬性後,您應該將其恢復爲默認值。

例如,你可以寫這樣的:

Set8087CW(Default8087CW); 

在我的代碼庫的言論表明,你只需要在第一次的VCL打印機代碼已被初始化之後做到這一點。所以你可以在你的程序啓動時處理這個問題。閱讀Printer.PrinterIndex,然後立即將控制字設置爲其所需的值。

+0

哇!正確的目標!我已將它添加到「創建」,並且我工作得很好。剛剛添加了兩行:Printer.PrinterIndex; Set8087CW(Default8087CW); ,然後錯誤消失了。非常感謝您的幫助。 – briast