一个关于浮点计算的问题,看起来很简单!(100分)

  • 主题发起人 主题发起人 weiliu
  • 开始时间 开始时间
W

weiliu

Unregistered / Unconfirmed
GUEST, unregistred user!
大家试试以下的简单程序,当max_float_num的值为3.1e4时完全正常,而此值为4.1e4时为何像死机一样计算不出来了?

var
float_num,float_operator,max_float_num:single;
begin
float_num:=1e-3;
float_operator:=float_num;
max_float_num:=3.1e4;
while float_num-max_float_num<1e-6 do
begin
float_num:=(float_num+float_operator+float_operator-float_operator)*float_operator/float_operator;
end;
showmessage(floattostr(float_num));
end;
 
应该是值太大,运算次数增多的原因吧。你可以加点调试信息

while float_num-max_float_num<1e-6 do
begin
float_num:=(float_num+float_operator+float_operator-float_operator)*float_operator/float_operator;
Memo1.Lines.Add(Format('%f', [float_num]))
//Hero
Application.ProcessMessages;
end;
 
xianguo,
值没有大多少啊,3.1e4一秒钟就可以算出来,4.1e4等了十几分钟了还没有反应。
 
3.1e4时,循环了 24245679 次
 
//加点调试信息
procedure TForm1.Button1Click(Sender: TObject);
var
float_num,float_operator,max_float_num:single;
ii : Integer;
begin
float_num:=1e-3;
float_operator:=float_num;
max_float_num:=4.1e4;
Caption := Format('%f : %f', [max_float_num, float_num]);
ii := 0;
while float_num-max_float_num<1e-6 do
begin
float_num:=(float_num+float_operator+float_operator-float_operator)*float_operator/float_operator;
Inc(ii);
if ii mod 100000 = 0 then Memo1.Lines.Add(Format('%d : %f', [ii, float_num]));
//Application.ProcessMessages;
end;
Memo1.Lines.Add(Format('%d', [ii]));
end;
 
执行到32768时死循环了
 
数据类型定义的问题

float_num,float_operator,max_float_num:double
//single -> Double
 
xianguo,
我的这个程序出于特殊原因,不能用DOUBLE的数,只能用SINGLE的数。
一个SINGLE数不可能仅仅表达到3.2767E4吧。
而且你如果把float_num:=1e-2;就可以让4.1E4计算通过。
 
这条语句:float_num:=(float_num+float_operator+float_operator-float_operator)*float_operator/float_operator;不就是float_num:=float_num*2吗?
为何要写的这么复杂啊?
 
eonzhang,
这个程序比较特殊,是必须这么来写的,这跟我不用DOUBLE而用SINGLE一样,是有特殊要求的。
 
3.1e4---循环了24245679次。
你的特殊要求很是奇怪
 
涉及到硬件对实数表示的误差,由于误差的积累,可能会出现各种怪异的问题!!!
 
single只表达7位有效数字
double有16位有效数字
 
这就是传说中的精度丢失,如果整数部分越大,小数部分精度就越小,大于32768说明精度就必须大于0.001否则是没有用处的,即:
A:=A + 0.001,如果A〉32768, 那么计算机不能区分A值不会变化
 
女儿刚出生,网上show一下,欢迎大家访问我的博客,以后我也会逐渐完善我的博客,使大家受益:
http://blog.163.com/gongyuzhuo ,也很想结识一些朋友,我在青岛
 
特殊需求啥?是不是要改的地方太多了
 
你如果不把你的特殊需求说明白,很难帮你想办法。你的计算实在是太怪异了。而且,违反原则。
 
多人接受答案了。
 
后退
顶部