Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 键入浮点值还是使用math.h floor*函数?_C_Algorithm_Floating Point_Casting - Fatal编程技术网

C 键入浮点值还是使用math.h floor*函数?

C 键入浮点值还是使用math.h floor*函数?,c,algorithm,floating-point,casting,C,Algorithm,Floating Point,Casting,我正在用C编写一个的实现 问题其实很简单,我需要使用浮点运算进行线性插值,以找到正确的索引,最终得到一个整数结果 特别是我的探测器索引是: t = i + floor((((k-low)/(high-low)) * (j-i))); 其中,i,j,k,t是无符号整数,high,low是双精度整数 这是否等于: t = i + (unsigned int)(((k-low)/(high-low)) * (j-i)); 有什么理由我真的想在一个简单的(int)类型转换上使用math.h floo

我正在用C编写一个的实现

问题其实很简单,我需要使用浮点运算进行线性插值,以找到正确的索引,最终得到一个整数结果

特别是我的探测器索引是:

t = i + floor((((k-low)/(high-low)) * (j-i)));
其中,i,j,k,t是无符号整数,high,low是双精度整数

这是否等于:

t = i + (unsigned int)(((k-low)/(high-low)) * (j-i));

有什么理由我真的想在一个简单的(int)类型转换上使用math.h floor*函数吗?

它们只对正数等效。根据C99规范(§6.3.1.4/1):

当实际流动类型的有限值转换为除
\u Bool
以外的整数类型时, 舍弃小数部分(即,该值向零截断)。如果 整数部分不能用整数类型表示,行为未定义


因此,对于正数,将浮点值强制转换为整数类型的结果等同于调用
floor
,而对于负数,则等同于调用
ceil
,它们仅对正数等效。根据C99规范(§6.3.1.4/1):

当实际流动类型的有限值转换为除
\u Bool
以外的整数类型时, 舍弃小数部分(即,该值向零截断)。如果 整数部分不能用整数类型表示,行为未定义


因此,对于正数,将浮点值强制转换为整数类型的结果相当于调用
floor
,而对于负数,则相当于调用
ceil
,当值小于0时,它们是不同的

floor(-1.5) = -2.0
(int)-1.5 = 1

当值小于0时,它们是不同的

floor(-1.5) = -2.0
(int)-1.5 = 1

在你的情况下,它们是等价的。但对于负数

g++> printf("%g %d %u\n", floor(-5.5), (int)(-5.5), (unsigned)(-5.5));
-6 -5 0
(实际上,铸造一个负实数≤ -1到无符号整数是实现定义的(或未定义的行为?)


另外,
floor
返回一个double,因此
i+floor(…)
将作为浮点运算而不是整数运算执行。

在您的情况下,它们是等效的。但对于负数

g++> printf("%g %d %u\n", floor(-5.5), (int)(-5.5), (unsigned)(-5.5));
-6 -5 0
(实际上,铸造一个负实数≤ -1到无符号整数是实现定义的(或未定义的行为?)


另外,
floor
返回一个double,因此
i+floor(…)
将作为浮点运算而不是整数运算执行。

我明白了,感谢您提供详细信息。好消息是:((k-low)/(high-low))*(j-i)如果算法编码正确,则保证>=0(因为它毕竟是数组的索引)。因此,这似乎是一个合适的选择。谢谢。@nobody:请注意,从性能角度来看,转换为整型可能不会比使用
floor
更快。转换为整数类型可能需要写入内存(在x86上,几乎可以保证),而调用
floor
可能不需要,因为其结果是浮点值。您的里程数可能会有所不同,但请注意过早和/或误导的优化。我明白了,谢谢您提供详细信息。好消息是:((k-low)/(high-low))*(j-i)如果算法编码正确,则保证>=0(因为它毕竟是数组的索引)。因此,这似乎是一个合适的选择。谢谢。@nobody:请注意,从性能角度来看,转换为整型可能不会比使用
floor
更快。转换为整数类型可能需要写入内存(在x86上,几乎可以保证),而调用
floor
可能不需要,因为其结果是浮点值。您的里程数可能会有所不同,但请注意过早和/或误导的优化。将负实值转换为无符号整数类型是未定义的:“如果整数部分的值不能用整数类型表示,则行为是未定义的”(§6.3.1.4/1)。这有点有趣,因为将负整数值强制转换为无符号整数类型的定义很明确:“如果新类型是无符号的,则通过反复增加或减少新类型中可以表示的最大值的一个值来转换该值,直到该值在新类型的范围内”(§6.3.1.3/2)。(引用自C99规范)。@James:Footnote(50)写道:“当整数类型的值转换为无符号类型时,不需要执行实数浮点类型的值转换为无符号类型时执行的余数运算。”这似乎表明预期的转换是
real->signed->unsigned
,使我无法确定它是否应该是未定义的(如6.3.1.4)或实现定义的(6.3.1.3)。将负实值转换为无符号整数类型是未定义的:“如果整数部分的值不能用整数类型表示,则行为是未定义的”(§6.3.1.4/1)。这有点有趣,因为将负整数值强制转换为无符号整数类型的定义很明确:“如果新类型是无符号的,则通过反复增加或减少新类型中可以表示的最大值的一个值来转换该值,直到该值在新类型的范围内”(§6.3.1.3/2)。(引用自C99规范)。@James:Footnote(50)写道:“当整数类型的值转换为无符号类型时,不需要执行实数浮点类型的值转换为无符号类型时执行的余数运算。”这似乎表明预期的转换是
real->signed->unsigned
,这使我无法确定它是否应该是未定义的(如6.3.1.4中所述)或实现定义的(6.3.1.3)。