如何在 Delphi7 中将浮点数转换为最大为 2个十进制数字的字符串?
我尝试使用:
FloatToStrF(Query.FieldByName('Quantity').AsFloat, ffGeneral, 18, 2, FS);
但是,使用上述方法,有时会返回两个以上的十进制数字,即。结果是:15,60000009
答案 0 :(得分:4)
使用ffFixed
代替ffGeneral
。
ffGeneral
忽略Decimal
参数。
使用ffGeneral
时,18
表示您需要18个有效十进制数字。然后,例程将以最短的方式表示该数字,并在必要时使用科学计数法。 2
被忽略。
使用ffFixed
时,是想在小数点后加上2
位数字。
如果您想知道为什么有时有时会获得不精确的值,那么在此站点上可以找到很多东西,其他的东西也可以解释浮点数的工作原理。
在这种情况下,AsFloat
返回的double
与大多数(其他)浮点格式一样,将其值存储在二进制中。以相同的方式,不能用有限的十进制数写1/3,也不能用有限的位数用二进制表示15.6。系统选择可以存储在double
中的最接近的可能值。精确值(以十进制表示)是:
15.5999999999999996447286321199499070644378662109375
如果要求精度为16位,则该值将四舍五入为15.6。但是您要求输入18位数字,因此得到15.59999999999999999996。
答案 1 :(得分:0)
如果您确实是要写的内容(最多2个十进制数字),而不是始终是2个十进制数字,那么注释中的两个代码段将不会给出您想要的内容(它们将返回一个始终有两个十进制数字,即返回1.00作为“ 1.00”(对于格式,返回“ 1,00”,具体取决于您的小数点)。
如果您确实想要一个最大MAX 2个十进制数字的选项,则必须对返回的字符串进行一些后期处理。
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”。 TEN(最多2个十进制数字)将返回“ 10”。
最终的IF语句应该真正测试正确的小数点,但是我认为除句点或逗号以外的任何其他值都不是可能的,并且如果其中的任何一个在去除所有字符后保留为字符串中的最后一个字符末尾为零,则必须为小数点。
还请注意,此代码假定字符串在第一个字符处的索引为1,就像在Delphi 7中一样。如果在较新的Delphi版本中需要此代码用于移动编译器,则需要更新码。我将把练习留给读者:-)。
答案 2 :(得分:0)
我在我的应用程序中使用此功能:
function sclCurrencyND(Const F: Currency; GlobalDegit: word = 2): Currency;
var R: Real; Fact: Currency;
begin
Fact:= power(10, GlobalDegit);
Result:= int(F*Fact)/Fact;
end;