Delphi/Borland Pascal STR 程序如何轮转

dum*_*uch 5 delphi pascal rounding delphi-2007

Borland Pascal 7 和 Delphi 2007 都得到了过程 STR,它接受一个数字、一个长度和一个精度,并将其转换为这样的字符串:

str(9.234:5:1, s); // -> s = '  9.2'
Run Code Online (Sandbox Code Playgroud)

如果舍入是非歧义的,一切都很好,但如果不是(0.5 -> 向上或向下?),则存在问题:它似乎取决于 BP 中的浮点数据类型,但在 Delphi 2007 中显然是一致的:

BP:

var
  e: extended;
  d: double;
begin
  d := 2.15;
  e := 2.15;
  str(d:5:1, s); { -> s = '  2.1' }
  str(e:5:1, s); { -> s = '  2.2' }
  { but: }
  d := 2.25
  e := 2.25
  str(d:5:1, s); { -> s = '  2.3' }
  str(e:5:1, s); { -> s = '  2.3' }
Run Code Online (Sandbox Code Playgroud)

我找不到任何关于双打如何四舍五入的规则,而显然扩展总是四舍五入。

Delphi 2007 显然总是与数据类型无关。

有人知道如何在 BP 中为双值进行四舍五入吗?

我想知道,因为我正在将一些使用双精度的 Borland Pascal 代码移植到 Delphi 2007,当我比较输出时,由于 STR 过程中的舍入而导致不一致。这些对结果并不重要,但很难发现重要的差异。

klu*_*udg 4

d = 2.15 和 d = 2.25 的情况不同:

2.15 无法用浮点格式精确表示,因此如果不分析给定浮点格式的浮点值的二进制表示,就不可能说出该值是如何舍入的;

2.25以float格式精确表示,舍入结果必须是可预测的;

我测试了一些以浮点格式精确表示的值的舍入,发现 STR 总是向上舍入正值,向下舍入负值。STR 不遵循“银行四舍五入”,例如:

  d := 2.25;
//  d:= roundto(d, -1);  banker's rounding is 2.2
  str(d:5:1, s); { -> s = '  2.3' }

  d:= 2.75;
//  d:= roundto(d, -1);  banker's rounding is 2.8
  str(d:5:1, s); { -> s = '  2.8' }
Run Code Online (Sandbox Code Playgroud)