真正的原因是计算机对浮点数储存的问题。事实上类似0.005这样的数在获得最佳精度的时候为0.0049999999999xxx。 如果要获得0.005的小数点后2位舍入结果,我认为应该这样操作:float x = 0.005 FormatFloat("0.000",x); float s = Round(x*100)/100;
瞧定义: Currency is a fixed-point data type that minimizes rounding errors in monetary calculations. It is stored as a scaled 64-bit integer with the four least-significant digits implicitly representing decimal places. When mixed with other real types in assignments and expressions, Currency values are automatically divided or multiplied by 10000.好事做到底,我帮你把 Round45 改了一下,现在精确到8位都没问题了
这是我写的一个函数,你试试。double DOLPHI_Round( double lX ) { double lS; int iS = floor(lX*1000); if( iS%10 >= 5 ) { lS = (double)(iS/10+1)/100; } else { lS = (double)(iS/10)/100; } return lS; }
这是更新的,自定义小数点后几位double DOLPHI_Round( double lX ,int iLength) { int iMul = 1; for(int i=;i<iLength-1;i++) { iMul *= 10; } double lS; int iS = floor(lX*iMul*10); if( iS%10 >= 5 ) { lS = (double)(iS/10+1)/iMul; } else { lS = (double)(iS/10)/iMul; } return lS; }
贴——D6对ROUNDTO的定义(math.pas): function TForm1.myRoundTo(const AValue: Double; const ADigit: TRoundToRange): Double; var LFactor: Double; begin LFactor := IntPower(10, ADigit); Result := Round(AValue / LFactor) * LFactor; end;
我确信D6的RoundTo对此问题不能解决!
UnitMathCategoryArithmetic routinesfunction IntPower(const Base: Extended; const Exponent: Integer): Extended register;DescriptionIntPower raises Base to the power specified by Exponent.
如果要获得0.005的小数点后2位舍入结果,我认为应该这样操作:float x = 0.005
FormatFloat("0.000",x);
float s = Round(x*100)/100;
Currency is a fixed-point data type that minimizes rounding errors in monetary calculations. It is stored as a scaled 64-bit integer with the four least-significant digits implicitly representing decimal places. When mixed with other real types in assignments and expressions, Currency values are automatically divided or multiplied by 10000.好事做到底,我帮你把 Round45 改了一下,现在精确到8位都没问题了
{
double lS;
int iS = floor(lX*1000); if( iS%10 >= 5 )
{
lS = (double)(iS/10+1)/100;
}
else
{
lS = (double)(iS/10)/100;
}
return lS;
}
{
int iMul = 1;
for(int i=;i<iLength-1;i++)
{
iMul *= 10;
}
double lS;
int iS = floor(lX*iMul*10); if( iS%10 >= 5 )
{
lS = (double)(iS/10+1)/iMul;
}
else
{
lS = (double)(iS/10)/iMul;
}
return lS;
}
RoundTo(1.234, -2) 1.23
RoundTo(1.235, -2) 1.24
RoundTo(1.245, -2) 1.24
function Round45_EX(GetOldCurr: Double;Digits: integer=2): Double;
var tmpCurr:Double;
begin
tmpCurr:= GetOldCurr * (IntPower(10,Digits)); // 小数点右移digits位
if Abs(Frac(tmpCurr)) < 0.5 then
tmpCurr:= Int(tmpCurr) // 保留整数部分
else
if tmpCurr>0 then
tmpCurr:= Int(tmpCurr)+1
else tmpCurr:= Int(tmpCurr)-1; // 进位
Result:= tmpCurr /IntPower(10,Digits); // 小数点回移
end;
Math
var
LFactor: Double;
begin
LFactor := IntPower(10, ADigit);
Result := Round(AValue / LFactor) * LFactor;
end;另外,Round函数在Delphi的帮助中已经说得很明白,是四舍六入,五取双
float s = Round(x*100+0.5)/100
来做
好像也解决不了问题吧?
var
ss: string;
p: integer;
begin
str(s : 0 : 10, ss);
p := pos('.', ss) + digits + 1;
result := StrToFloat(copy(ss, 1, p - 1));
if ss[p] >= '5' then
result := 1 / IntPower(10, digits) + result;
end;
我试一试aliceZooZ的看!
唉,没有D6,只能关注了。
function TForm1.myRoundTo(const AValue: Double;
const ADigit: TRoundToRange): Double;
var
LFactor: Double;
begin
LFactor := IntPower(10, ADigit);
Result := Round(AValue / LFactor) * LFactor;
end;
>1."mod"這個指令只能下在integer上...
>但是我現在有須要用一個float去除一個整數...
>然後只求它的餘數...??????????
>
>2.我現在要讀一個float的整數部份...
>(ie.想要float to integer)
>我該怎麼辦..??!!
>
>新手上路請不吝指教...!!function Round(X: Extended): Int64;
function Trunc(X: Extended): Int64;Round 为四舍五入,Trunc 为舍整
这种处理理应在数据库定义时处理,这样在数据更新时底层自动无误进行快速处理。(用触发器比较好)。如果一定要在前端处理的话我也没意见。
begin
....
end;