【问题标题】:Decimal rounding and printer selection小数舍入和打印机选择
【发布时间】:2014-04-28 14:10:12
【问题描述】:

我使用 Delphi RAD Studio 2010 和来自 http://cc.embarcadero.com/item/21909 的 DecimalRounding_JH1.pas。

它工作得很好,但我不知道为什么,在一些旧机器(带有 Windows XP SP3 的 Pentium IV)中,访问printer.printerindex 后回合失败。我检查了问题不是 Windows XP,因为它可以在具有此操作系统的其他机器上运行。

我做了一个简单的项目,它使用带两位小数的 DecimalRounding_JH1 (drHalfUp) 舍入扩展值(1.105 -> 舍入为 1.11)。但是如果我读了printer.printerindex,那么1.105会舍入到1.10)。

我认为这可能是“FDIV 错误”,但使用“FDIV safe”编译并不能解决问题。

代码:

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;

提前致谢。

【问题讨论】:

  • FDIV 错误影响了原始 Pentium。我可以向您保证,您没有运行其中之一。还值得指出的是,问题中的代码有些缺陷。 1.105 的值不能以二进制浮点数表示。看看这里以查看最接近的可精确表示的浮点值:pages.cs.wisc.edu/~rkennedy/exact-float?number=1.105 最后,我不确定您为什么要使用扩展。它的性能很差,只存在于 x86 上。
  • 感谢您的帮助,但我有点绝望,我尝试了任何方法,尽管我知道 FDIV 是旧 Pentium 中的一个错误。代码(1.105)是一个例子,但正如我所说,在 Printer.printerindex 之后它并不好。但大卫赫弗南的解决方案一切正常。谢谢。

标签: delphi decimal rounding


【解决方案1】:

系统打印机库的某些部分有修改 8087 控制字的相当讨厌的习惯。使用Printer的方法和属性后应该恢复到默认值。

例如,你可以这样写:

Set8087CW(Default8087CW);

我的代码库中的 cmets 建议您只需要在第一次初始化 VCL 打印机代码后执行此操作。所以你可以在你的程序启动时处理这个问题。读取Printer.PrinterIndex,然后立即将控制字设置为所需的值。

【讨论】:

  • 哇!正中目标!!!我已将其添加到“创建时”中,并且效果很好。刚刚添加了两行:Printer.PrinterIndex; Set8087CW(默认8087CW); ,然后错误就消失了。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 2013-11-08
  • 1970-01-01
  • 2012-12-23
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多