// value will always be in the range of [0.0 - maximum]
float obtainRatio(float value, float maximum){
if(maximum != 0.f){
return value / maximum;
}else{
return 0.f;
}
}
maximum
的范围可以是任何内容,包括负数。 value
的范围也可以是任何东西,但该功能仅需要使" sense"当输入在[0.0 - maximum]
范围内时。输出应始终在[0.0 - 1.0]
我有两个问题,我想知道这个问题:
答案 0 :(得分:14)
这是一个迟到的答案,澄清了与问题相关的一些概念:
在浮点数中,除零不是整数除零的致命错误。
由于您知道value
介于0.0
和maximum
之间,因此可以发生的唯一除零是0.0 / 0.0
,定义为生成NaN
。浮点值NaN
是函数obtainRatio
返回的完全可接受的值,实际上是一个比0.0
更好的异常值,因为您提出的版本正在返回。
浮动之间<=
的定义没有任何近似值。当a <= b
略高于a
时,b
不有时评估为true。如果a
和b
是两个有限float
个变量,那么当a <= b
所代表的理性小于或等于理性代表时,a
会完全评估为真按b
。人们可能感觉到的唯一一点小故障实际上并不是一个小故障,而是对上述规则的严格解释:+0.0 <= -0.0
评估为真,因为“+0.0
代表的理性”和{-0.0
代表的理性1}}“都是0。
同样,浮动之间没有==
近似值:两个有限float
个变量a
和b
生成a == b
当且仅当a
表示的理性和b
表示的理性相同时才为真。
在if (f != 0.0)
条件下,f
的值不能表示为零,因此f
的除法不能除以零。分裂仍然可能溢出。在value / maximum
的特定情况下,由于您的函数需要0 ≤ value ≤ maximum
,因此不会出现溢出。而且我们不需要怀疑前提条件中的≤
是否意味着理性之间的关系或者浮点数之间的关系,因为这两者基本上是相同的。
C99允许浮点表达式具有额外的精度,这已经被编译器制造商错误地解释为使得浮点行为不稳定的许可(到程序{{ 1}}可能会在某些情况下打印“哦”。
实际上,提供IEEE 754浮点并将if (m != 0.) { if (m == 0.) printf("oh"); }
定义为非负值的C99编译器在测试后不能更改FLT_EVAL_METHOD
的值。变量m
设置为上次分配时表示为float的值,该值表示为0或者不是。只有操作和常量才能具有过高的精度(参见C99标准,5.2.4.2.2:8)。
对于GCC,最新版本使用m
执行适当的操作,-fexcess-precision=standard
暗示。
David Monniaux description几年前C中浮点状态的悲惨状态(2007年发布的第一版)。 David的报告并没有尝试解释C99标准,而是通过实例来描述C中浮点计算的实际情况。这种情况得到了很大的改善,这要归功于编译器的标准兼容性得到了改善,因为SSE2指令集使整个问题变得没有实际意义。
约瑟夫·迈尔斯的2008 mailing list post描述当时海湾合作委员会当前GCC的情况(不好),他如何解释标准(好)以及他如何在GCC中实施他的解释(好) )。
答案 1 :(得分:4)
在这种情况下,范围有限,应该没问题。一般来说,首先检查零会阻止除零,但如果除数接近于零并且被除数是一个大数,那么仍然有可能出现溢出,但在这种情况下,如果除数是一个很大的数,则分红将很小。除数很小(两者都可以接近零而不会导致溢出)。