在Delphi7中,如何将浮点数转换为最多2个小数位的字符串?
我尝试使用以下方法:
FloatToStrF(Query.FieldByName('Quantity').AsFloat, ffGeneral, 18, 2, FS);
但是有时候会返回超过2位小数,即结果为:15.60000009
在Delphi7中,如何将浮点数转换为最多2个小数位的字符串?
我尝试使用以下方法:
FloatToStrF(Query.FieldByName('Quantity').AsFloat, ffGeneral, 18, 2, FS);
但是有时候会返回超过2位小数,即结果为:15.60000009
请使用ffFixed
代替ffGeneral
。
ffGeneral
忽略Decimal
参数。
当您使用ffGeneral
时,18
表示您想要18个有效的小数位。然后,该程序将以最短的方式表达该数字,必要时使用科学计数法。 2
将被忽略。
当您使用ffFixed
时,您表示您希望小数点后有2
位。
如果您想知道为什么有时会得到看起来不精确的值,可以在本网站和其他网站上找到很多解释浮点数如何工作的内容。
在本例中,AsFloat
返回一个double
,就像(大多数)其他浮点格式一样,它以二进制存储其值。 就像1/3无法用有限的数字写成十进制一样,15.6也无法用有限的位数在二进制中表示。 系统选择可以存储在double
中的最接近的可能值。 精确的值以十进制表示为:
15.5999999999999996447286321199499070644378662109375
如果您要求16位精度,则该值将四舍五入为15.6。 但是您要求18位数字,因此得到15.5999999999999996。
FUNCTION FloatToStrMaxDecimals(F : Extended ; MaxDecimals : BYTE) : STRING;
BEGIN
Result:=Format('%.'+IntToStr(MaxDecimals)+'f',[F]);
WHILE Result[LENGTH(Result)]='0' DO DELETE(Result,LENGTH(Result),1);
IF Result[LENGTH(Result)] IN ['.',','] THEN DELETE(Result,LENGTH(Result),1)
END;
另一种(可能更快的)实现方式可以是:
FUNCTION FloatToStrMaxDecimals(F : Extended ; MaxDecimals : BYTE) : STRING;
BEGIN
Result:=Format('%.'+IntToStr(MaxDecimals)+'f',[F]);
WHILE Result[LENGTH(Result)]='0' DO SetLength(Result,PRED(LENGTH(Result)));
IF Result[LENGTH(Result)] IN ['.',','] THEN SetLength(Result,PRED(LENGTH(Result)))
END;
此函数将返回一个浮点数,最多指定小数位数。例如,MAX为2的一半将返回“0.5”,MAX为2的三分之一将返回“0.33”,MAX为2的两个三分之一将返回“0.67”。MAX为2的TEN将返回“10”。
最终的IF语句应该真正测试适当的小数点,但我认为除了句号或逗号以外,不可能有其他值,并且如果这些字符中的一个在从末尾剥离所有零后留下作为最后一个字符,则它必须是小数点。
还要注意,此代码假定字符串使用1作为第一个字符进行索引,就像在Delphi 7中总是这样一样。如果您需要此代码用于更新版本的Delphi移动编译器,则需要更新代码。我会把这个练习留给读者 :-).
MaxDecimals
作为开放数组的参数,而是将其包含在字符串中?Format('%.*f', [MaxDecimals, F]);
。这样更容易阅读。 - Rudy Velthuisfunction sclCurrencyND(Const F: Currency; GlobalDegit: word = 2): Currency;
var R: Real; Fact: Currency;
begin
Fact:= power(10, GlobalDegit);
Result:= int(F*Fact)/Fact;
end;
Format('%3.2f', [yourFloatValue])
是怎么样的呢? - Rudy Velthuisstr(myfloat:18:2,mystring)
- gammatester