Val过程是否使用DecimalSeparator?

zig*_*zig 6 delphi delphi-5

StrToFloat使用DecimalSeparator格式设置.

似乎Val只接受包含.小数分隔符的字符串.

_ValExt(Val调用)中的ASM代码看起来它不使用DecimalSeparator.

我可以安全地依赖Val接受带有.小数分隔符的实数字符串的事实(?)吗?

Rud*_*uis 8

Val是古老的,低水平的,使用起来有点棘手.我不建议在用户代码中使用它.而是使用其它程序来扫描的值,比如StrToFloat,等等.如果你使用StrToFloatTFormatSettings.Invariant,你可以肯定,你得到的点('.')作为小数点分隔符.

看看下面的测试代码.在我的德语系统中,小数点分隔符是逗号.所以我尝试了以下方法:

procedure Test;
var
  E: Extended;
  S: Single;
  I: Integer;
  Code: Integer;
begin

  Val('1.234', E, Code);
  if Code = 0 then
    Writeln('1.234 Extended: ', E)
  else
    Writeln('1.234 Extended: Error, code = ', Code);

  Val('1,234', E, Code);
  if Code = 0 then
    Writeln('1,234 Extended: ', E)
  else
    Writeln('1,234 Extended: Error, code = ', Code);

  Val('1.234', S, Code);
  if Code = 0 then
    Writeln('1.234 Single: ', S)
  else
    Writeln('1.234 Single: Error, code = ', Code);

  Val('1234', I, Code);
  if Code = 0 then
    Writeln('Integer: ', I)
  else
    Writeln('Integer: Error, code = ', Code);

end;
Run Code Online (Sandbox Code Playgroud)

输出是:

1.234 Extended:  1.23400000000000E+0000
1,234 Extended: Error, code = 2
1.234 Single:  1.23399996757507E+0000
Integer: 1234
Run Code Online (Sandbox Code Playgroud)

这清楚地表明,Val不使用系统定义的小数分隔符,只接受不变的小数分隔符,即'.'.System.ValIMO,这里的文档有点误导.

UPDATE

似乎我使用E而不是S代码的"单个部分".如果你传递了一个Single,显然你也得到正确的值,所以我猜编译器(它知道传递了什么)以某种方式将这些信息传递给内部例程.

查看CPU窗口,您可以看到,如果传入浮点类型,System.@ValExt则调用它,它返回FPU堆栈顶部的值(ST(0)).编译器比添加适当的代码,以存储值(FSTP TBYTE,FSTP QWORDFSTP DWORDExtended,DoubleSingle分别).

类似地,对于整数变量(最多32位),System.@ValLong调用它,返回一个Integer输入EAX,并且编译器添加适当的代码来存储正确大小的值.对于64位整数,@ValInt64调用,返回一个值EDX:EAX.

FWIW,它还表明 Writeln 不使用系统定义的小数分隔符.

  • 在扩展有用的情况下,真的非常少 (3认同)
  • 不,这不是标准.默认的实际值类型是Double.扩展仅在x86上存在. (2认同)