下溢和浮点数学 [英] Underflow and floating-point math

查看:67
本文介绍了下溢和浮点数学的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一篇文章指出:在浮点数学中,如果你经常划分一个足够大的数字,那么你将永远能够获得
到达a鉴于有限的精度,你可以得到的值太小而无法与零区分开来。


当一个值太小而无法与零区分时会发生什么? ;

以上分区?下溢?


这是什么意思足够频繁因为只有一个分区应该足够导致两个浮点数之间的分割下溢吗?


当发生下溢时,上述分区的结果应该是将

视为未定义的行为?换句话说,结果可以是任何浮动的

数字或只是无意义的数字。这是正确的吗?


感谢提前!

解决方案

tings写道:

一篇文章指出:在浮点数学中,如果你经常划分足够大的数字,你将始终能够达到一个值考虑到你所拥有的有限精度,太小而无法与零区分。

当一个值太小而无法与零区分时会发生什么?是通过以上部门达成的吗?溢?


您到零时因为无法将值与

零区分开来。 IOW:

\ forall浮点数f

\出现浮点数g,自然数n:

" f /(克^ N)" ==零

其中expr表示浮点表达式的评估

算术。

我们有0< h = f / g ^ n< min {浮点数e | e> 0}

但是h足够小,可以舍入到零。


您能否通过下溢来定义_exactly_的含义?


这是什么意思足够频繁因为只有一个分区应足以导致两个浮点数之间的分割下溢?


示例:

#include< math.h>

#include< float.h>

#include< stdio.h>


int main(无效)

{

double f = 2.0 * DBL_MIN;

double g = 1.0 / DBL_EPSILON;

unsigned int n = 3;


printf("%* 。* g\ n",DBL_DIG + 1,DBL_DIG,f / pow(g,n));


返回0;

}

应该适用于大多数机器。


当发生下溢时,上述划分的结果应视为未定义的行为?换句话说,结果可以是任何浮动数字或仅是无意义的数字。这是正确的吗?




No.

干杯

Michael

-

电子邮件:我的是/ at / gmx / dot / de地址。


tings写道:

一篇文章指出:在浮点数学中,如果你经常划分足够大的数字,你总是能够达到一个太小而不能与零区分的值,因为有限的精度
你有。


你不能确定除以一个大数字就可以了。

。会有很多单个数字可以除以

来获得下溢,毕竟...

(a / b)/ c = a /(b * c)


要找到你能选择的最小幅度

的数量需要做更多的工作......无论如何,它只是陈述它的一种方式。

如果你把数字分成不是那么大,那就是一样的。

足够多次,你最终会发生下溢。


如果您所做的只是数字的划分,其数量大小为
big,那么如果您执行<,那将是最终结果这些划分[自己]就足够了。

这是什么意思足够频繁因为只有一个分区应足以导致两个浮点数之间的分割下溢?


我相信一个潜在的假设是你正在执行其他操作并保持累积结果,你不是只需要b $ b划分但执行计算涉及系统的其他事情的应用,也许是许多操作(增加,增加,减去乘法或减法)以及分裂。


所以经常正在表征你将当前结果除以你的数量的大小,以减少其幅度

与将增加其幅度的操作相比

你的下一个结果。


足够经常意味着你的分歧不是那么分散或交错与其他增加的操作

的数量,你远离零。


即如果你有


双值= 500;


for(i = 0; i< 10000; i ++){

value = value * 100 - 1;

value = value / 100 ;

}


你肯定会表现很多分歧,但''价值''

可能永远不会如此接近将四舍五入为0.

只有大约1/3的操作是分部,而1/3的

操作增加了数值。


所以这些部门可能不够频繁。

现在,如果你做了
for(i = 0;我< 10000; i ++){

value = value * 100 + 1;

for(k = 0; k <10; k ++){value = value / 100; }

}


您可能会发现需要经常划分。

当发生下溢时,上述划分的结果应该被视为未定义的行为?换句话说,结果可以是任何浮动数字或仅是无意义的数字。这是正确的吗?




这取决于你所做的事情的性质。在某些情况下,它可能暗示你可能会丢失精确度或

爆炸的东西,但是......


我不会一概而论,IMO ..你需要评估

结果是否符合你的期望,是否正确得到或者如果

下溢正在制造一团糟,你需要获得更高的精度

或以不同的方式执行计算。


我不知道任何硬性规定。

-Mysid


tings写道:

[snip]

当发生下溢时,上述划分的结果应被视为未定义的行为?换句话说,结果可以是任何浮动数字或仅是无意义的数字。这是正确的吗?




编号标准说明(第213页,7.12.1)


5如果数学结果的大小如此之小,以至于无法表示数学结果,而没有

非常的舍入误差,则结果下溢指定的类型.195)

如果结果下溢,该函数返回一个实现定义的

值,其大小不大于最小的标准化值
$ b指定类型的$ b正数;如果是整数表达式

math_errhandling& MATH_ERRNO是非零的,是否errno获得了

值ERANGE是实现定义的;如果是整数表达式

math_errhandling& MATH_ERREXCEPT是非零的,是否引发了??下溢??

浮点异常是实现定义的。




以lcc-win32编译器为例,我们有:

1)下溢被屏蔽并将近似为零。由于零

小于最小可表示数字,因此它符合

标准规格。


2)lcc-win32确实如此如果发生下溢,则不设置任何errno标志


3)如果用户在发生下溢之前用标准

函数fesetexceptionflag取消屏蔽下溢标志,则机器<每个下溢都会陷入
陷阱。


我希望这能说清楚。


jacob


An article states: "In floating point maths, where if you divide by a
sufficiently large number sufficiently often, you will always be able to
reach a value too small to distinguish from zero, given the finite precision
you have."

What happens when "a value too small to distinguish from zero" is reached by
the above division? Underflow?

What does it mean "sufficiently often" since only one division should be
enough to cause underflow in division between two floating point numbers?

When underflow happens, the result of the above division should be regarded
as "undefined behavior"? In other words, the result could be any floating
number or just a meanless "number." Is this correct?

THANKS IN ADVANCE!


解决方案

tings wrote:

An article states: "In floating point maths, where if you divide by a
sufficiently large number sufficiently often, you will always be able to
reach a value too small to distinguish from zero, given the finite precision
you have."

What happens when "a value too small to distinguish from zero" is reached by
the above division? Underflow?
You arrive at zero because the value cannot be distinguished from
zero. IOW:
\forall floating point numbers f
\exists floating point number g, natural number n:
"f/(g^n)" == "zero"
where "expr" means evaluation of the expression in floating point
arithmetics.
We have 0 < h=f/g^n < min{floating point number e| e>0}
but h is sufficiently small to be rounded to zero.

Could you please define what you mean _exactly_ by underflow?

What does it mean "sufficiently often" since only one division should be
enough to cause underflow in division between two floating point numbers?
Example:
#include <math.h>
#include <float.h>
#include <stdio.h>

int main (void)
{
double f = 2.0*DBL_MIN;
double g = 1.0/DBL_EPSILON;
unsigned int n = 3;

printf("%*.*g\n", DBL_DIG+1, DBL_DIG, f/pow(g, n));

return 0;
}
should work on most machines.

When underflow happens, the result of the above division should be regarded
as "undefined behavior"? In other words, the result could be any floating
number or just a meanless "number." Is this correct?



No.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.


tings wrote:

An article states: "In floating point maths, where if you divide by a
sufficiently large number sufficiently often, you will always be able to
reach a value too small to distinguish from zero, given the finite precision
you have."
You can''t be sure that dividing by just a large number will do
that though. There will be lots of single numbers you could divide by
to get underflow, and after all...
(a/b)/c = a/(b*c)

It would take more work to find the number of least magnitude
that you could pick... in any case, it''s just a way of stating it.
It''s the same if you divide numbers that aren''t so large,
enough times it will eventually happen that you get underflow.

If all you are doing is divisions by numbers whose magnitude is
big, then it''s going to be the end result if you performed
just enough of these divisions [by themselves].
What does it mean "sufficiently often" since only one division should be
enough to cause underflow in division between two floating point numbers?
I believe an underlying assumption is that you are performing
other operations and keeping a cumulative result, you are not
just dividing but performing a computation that involves systematic
application of something else, perhaps many operations (additions,
multiplications, or subtractions) as well as divisions.

So "often" is characterizing at what rate you are dividing your
current result by a large number which diminishes its magnitude
compared to operations that will amplify its magnitude in getting
your next result.

Being sufficiently often means that your divisions are not so
scattered or interleaved with other operations that increase
in magnitude that you stay away from zero.

i.e. if you had

double value = 500;

for(i = 0; i < 10000; i++) {
value = value * 100 - 1;
value = value / 100;
}

You will certainly be performing many divisions, but ''value''
will probably never be so close as to be rounded to 0.
Only about 1/3 of your operations are divisions, and 1/3 of your
operations increase value in number.

So the divisions were probably not often enough.

Now if you did

for(i = 0; i < 10000; i++) {
value = value * 100 + 1;
for(k = 0; k < 10; k++) { value = value / 100; }
}

You might find that to be dividing sufficiently often.
When underflow happens, the result of the above division should be regarded
as "undefined behavior"? In other words, the result could be any floating
number or just a meanless "number." Is this correct?



It depends on the nature of what you are doing. In some case it
could be suggesting a possibility that you lost precision or
something blew up, but...

I wouldn''t generalize that, IMO.. you need to evaluate whether the
result fits your expectations and is the right thing to get or if
the underflow is making a mess and you need to get a higher precision
or perform the computations differently.

I don''t know of any hard and fast rule.
-Mysid


tings wrote:
[snip]

When underflow happens, the result of the above division should be regarded
as "undefined behavior"? In other words, the result could be any floating
number or just a meanless "number." Is this correct?



No. The standard says (page 213, 7.12.1)

5 The result underflows if the magnitude of the mathematical result is
so small that the mathematical result cannot be represented, without
extraordinary roundoff error, in an object of the specified type.195)
If the result underflows, the function returns an implementation-defined
value whose magnitude is no greater than the smallest normalized
positive number in the specified type; if the integer expression
math_errhandling & MATH_ERRNO is nonzero, whether errno acquires the
value ERANGE is implementation-defined; if the integer expression
math_errhandling & MATH_ERREXCEPT is nonzero, whether the ??underflow??
floating-point exception is raised is implementation-defined.



Taking the lcc-win32 compiler as an example we have:
1) underflow is masked and will be approximated as zero. Since zero
is less than the smallest representable number it is within the
standard specs.

2) lcc-win32 does NOT set any errno flag if underflow occurs

3) If the user unmasks the underflow flag with the standard
function fesetexceptionflag before the underflow occurs, the machine
will trap at each underflow.

I hope this makes this clear.

jacob


这篇关于下溢和浮点数学的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆