delphi - 使 VarToDoubleAsString 使用 Delphi 设置(而不是操作系统设置)

标签 delphi floating-point variant

当将包含字符串值的 Variant 分配给浮点变量时,Delphi 调用 VarToDoubleAsString 进行转换,该转换又使用操作系统设置的小数点和千位分隔符(通过 VarR8FromStr)。如果必须更改 SysUtils.DecimalSeparator 和 SysUtils.ThousandSeparator ,就会出现问题。例如运行以下程序:

program VarStrToFloat;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Math;

function FormatFloatUsingDelphiSettings(Value: Extended): string;
begin
  Result := FormatFloat('#,##0.00', Value);
end;

procedure Test(const AMsg: string);
var
  r1, r2: Extended;
  s1, s2: string;
  v: Variant;
begin
  r1 := 5432.1;
  s1 := FormatFloatUsingDelphiSettings(r1);
  v := s1; // <== conversion uses OS settings
  r2 := v;
  s2 := FormatFloatUsingDelphiSettings(r2);

  Write(AMsg: 8, s1: 10, s2: 10, '  ');
  if SameValue(r1, r2) then
    Writeln('OK')
  else
    Writeln('FAIL');
end;

procedure SwapEm;
var
  tmp: Char;
begin
  tmp := DecimalSeparator;
  DecimalSeparator := ThousandSeparator;
  ThousandSeparator := tmp;
end;

begin
  Test('Default');
  SwapEm;
  Test('Changed');
  Readln;
end.

第一个测试工作正常,第二个测试失败。

有没有办法让 Variant 转换使用 SysUtils.DecimalSeparatorSysUtils.ThousandSeparator

最佳答案

您可以根据自己的喜好替换 varutils.pas 中的 VarR8FromStr 函数,VarToDoubleAsString 将使用它:

function MyConversion(const strIn: WideString; LCID: Integer; dwFlags: Longint;
    out dblOut: Double): HRESULT; stdcall;
const
  CResult: array [False..True] of HRESULT = (VAR_INVALIDARG, VAR_OK);
var
  s: string;
begin
  s := StringReplace(StrIn, ThousandSeparator, '', [rfReplaceAll]);
  Result := CResult[TryStrToFloat(s, dblOut)];
end;

[...]

begin
  varutils.VarR8FromStr := MyConversion;
  [...]

关于delphi - 使 VarToDoubleAsString 使用 Delphi 设置(而不是操作系统设置),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5090107/

相关文章:

Delphi 2010 Action 管理器和主菜单栏

javascript - 这 === 对浮点舍入不准确的 b/c 不起作用吗?

C++ 抽象变体实现

delphi - delphi 生成随机数

delphi - 我不应该从线程中显示表单或消息框吗?

c++ - 如何用逗号打印 double

c - 当 float 是函数的实际参数时,为什么我的计算机会任意更改 float 末尾的小数位?

c# - 是否可以创建变体值类型?

c++ - 将 boost::variant 传递给(来自)dll 是否安全?

Delphi - 是否可以禁用 Delphi 的表单延迟加载?