Как научить Delphi делать правильное округление дробных чисел?
Nomadic советует:
Целая коллекция способов -
Для решения этой проблемы мною написана функция, которую можно модифицировать для всех случаев. Смысл заключается в том, что рассматривается строка. После этого все проблемы с округлением снялись.
Function RoundStr(Zn:Real;kol_zn:Integer):Real; {Zn-значение; Kol_Zn-Кол-во знаков после запятой} Var snl,s,s0,s1,s2:String; n,n1:Real; nn,i:Integer; begin s:=FloatToStr(Zn); if (Pos(',',s)>0) and (Zn>0) and (Length(Copy(s,Pos(',',s)+1,length(s)))>kol_zn) then begin s0 := Copy(s,1,Pos(',',s)+kol_zn-1); s1 := Copy(s,1,Pos(',',s)+kol_zn+2); s2 := Copy(s1,Pos(',',s1)+kol_zn,Length(s1)); n := StrToInt(s2)/100; nn := Round(n); if nn >= 10 then begin snl := '0,'; For i := 1 to kol_zn - 1 do snl := snl + '0'; snl := snl+'1'; n1 := StrToFloat(Copy(s,1,Pos(',',s)+kol_zn))+StrToFloat(snl); s := FloatToStr(n1); if Pos(',',s) > 0 then s1 := Copy(s,1,Pos(',',s)+kol_zn); end else s1 := s0 + IntToStr(nn); if s1[Length(s1)]=',' then s1 := s1 + '0'; Result := StrToFloat(s1); end else Result := Zn; end; |
Все-таки работа со строками здесь излишество -
function RoundEx( X: Double; Precision : Integer ): Double; {Precision : 1 - до целых, 10 - до десятых, 100 - до сотых...} var ScaledFractPart, Temp : Double; begin ScaledFractPart := Frac(X)*Precision; Temp := Frac(ScaledFractPart); ScaledFractPart := Int(ScaledFractPart); if Temp >= 0.5 then ScaledFractPart := ScaledFractPart + 1; if Temp <= -0.5 then ScaledFractPart := ScaledFractPart - 1; RoundEx := Int(X) + ScaledFractPart/Precision; end; |
[001146]