ROUND,四舍五入问题的终极答案 (50分)

  • 主题发起人 主题发起人 zhtx
  • 开始时间 开始时间
Z

zhtx

Unregistered / Unconfirmed
GUEST, unregistred user!
BORLAND的ROUND函数只能取整,而且是统计学上的四舍五入(奇数进,偶数不进),
应用中很不方便,大家提出了很多解决方案,综合起来主要有以下几种:
1.先换算成整数再用round处理,再换算回原来的数据
存在问题:round的取整算法和常用的不一样
2.先换算成整数再+0.5,再用INT处理,再换算回原来的数据
存在问题:很多人编写的函数没有处理负数
3.用FORMATFLOAT函数处理
存在问题:一般的数据均能处理,也是很多人认为的正确的答案,
但如果处理的是运算结果,因运算结果是浮点数,可能存在误差,则结果就不对.
例:显示是1.085,但运算结果可能是1.08499999,则取两位小数的结果为1.08

在总结上述错误,参观论坛上各高手的论述,我提出我的终极四舍五入函数,
我认为是全面的,但可能还有错误,或有更简单的算法,欢迎大家批评指教!

function RoundFloat(f:double;i:integer):double;
var
s:string;
ef:extended;
begin
s:='#.'+StringOfChar('0',i);
ef:=StrToFloat(FloatToStr(f));//防止浮点运算的误差
result:=StrToFloat(FormatFloat(s,ef));
end;

上面函数有问题(在取整并且结果为0的时候出错),现修正如下:
function RoundFloat(f:double;i:integer):double;
var
s:string;
ef:extended;
SValue: string;
begin
s:='#.'+StringOfChar('0',i);
ef:=StrToFloat(FloatToStr(f));//防止浮点运算的误差
SValue := FormatFloat(s,ef);
if SValue <> '' then
result := StrToFloat(SValue)
else
result := 0;
end;
 
代码很简洁,我测试一下!
 
不是有roundto 吗
 
ugvanxk:roundto是什么函数,DELPHI中我没看见啊.
 
在math单元
 
s:=1.08499999;
sx:=RoundFloat(s,3);
str:=floatTostr(sx);
showmessage(str);
str:=format('%.3f',);
sx:=strTofloat(str);
str:=floatTostr(sx);
showmessage(str);
结果相同!!!
 
tulipfan:什么在math单元?那里没有什么roundto啊
linsb:你这段程序什么意思,我的例子是说对运算结果取2位小数,不是3位,因
运算结果表面是1.085,但实际是1.084999999,你的程序中除了我的函数,其他取2位小数
的结果都是1.08,而不是1.09!

 
楼主的函数很管用,解决了我正碰到的问题
不过没搞懂:FormatFloat(s,ef)
例如我取小数后三位的话s=#.000,
这里面的“#”是一种运算符?还是起什么
特殊作用,望楼主指教为谢!
 
cooler168:#代表数字,详细说明请看FORMATFLOAT函数说明
 
我最喜欢用的就是roundto了。不知道它有什么缺陷没有?
(到目前为止,我还没发现什么不好的。呵呵)
 
To zhtx:在D6里是有ROUNDTO的,你用帮助看看不就看到了
 
呵呵,这是ROUNDTO的帮助文件内容。
VCL Reference
RoundTo function
See also
Rounds a floating-point value to a specified digit or power of ten using 揃anker抯 rounding?

Unit

Math

Category

Arithmetic routines

type TRoundToRange = -37..37;
function RoundTo(const AValue: Double
const ADigit: TRoundToRange): Double;

Description

Call RoundTo to round AValue to a specified power of ten.

AValue is the value to round.

ADigit indicates the power of ten to which you want AValue rounded. It can be any value from ?7 to 37 (inclusive).

RoundTo uses 揃anker抯 Rounding?to determine how to round values that are exactly midway between the two values that have the desired number of significant digits. This method rounds to an even number in the case that AValue is not nearer to either value.

The following examples illustrate the use of RoundTo:

Expression Value

RoundTo(1234567, 3) 1234000
RoundTo(1.234, -2) 1.23
RoundTo(1.235, -2) 1.24
RoundTo(1.245, -2) 1.24

Note: The behavior of RoundTo can be affected by the Set8087CW procedure or SetRoundMode function.
 
哈哈,怪不得我在D5中找不到,原来是D6中的啊,嘿嘿,我用软件都比别人慢半拍,
等你们测试好稳定后再用.
 
> 2.先换算成整数再+0.5,再用INT处理,再换算回原来的数据
> 存在问题:很多人编写的函数没有处理负数
下面处理小数有什么问题?
Floor(x*1000+0.5)/1000 (三位小数)
 
-0.5555取三位小数是-0.556,你的算法是-0.555
 

Similar threads

I
回复
0
查看
484
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
581
import
I
后退
顶部