C++ 如果浮点范围更大,是否始终定义通过浮点的往返行为?
假设我有两种算术类型,一种是整数类型,C++ 如果浮点范围更大,是否始终定义通过浮点的往返行为?,c++,language-lawyer,c++14,floating-point-conversion,C++,Language Lawyer,C++14,Floating Point Conversion,假设我有两种算术类型,一种是整数类型,I,另一种是浮点类型,F。我还假设std::numeric\u limits::max()小于std::numeric\u limits::max() 现在,假设我有一个正整数值I。由于F的可表示范围大于I,F(I)应始终定义为行为 但是,如果我有一个浮点值f,使得f==f(I),那么I(f)定义得好吗?换句话说,I(F(I))是否总是定义行为 C++14标准的相关章节: 4.9浮点积分转换[conv.fpint] 浮点类型的prvalue可以转换为整数类
I
,另一种是浮点类型,F
。我还假设std::numeric\u limits::max()
小于std::numeric\u limits::max()
现在,假设我有一个正整数值I
。由于F
的可表示范围大于I
,F(I)
应始终定义为行为
但是,如果我有一个浮点值f
,使得f==f(I)
,那么I(f)
定义得好吗?换句话说,I(F(I))
是否总是定义行为
C++14标准的相关章节: 4.9浮点积分转换[conv.fpint]
bool
,请参见4.12.-结束注]bool
,则值
false
转换为零,值true
转换为一f
,使得f==f(I)
,那么I(f)
定义得好吗?换句话说,I(F(I))
是否总是定义行为
没有
假设I
是有符号2的补码32位整数类型,F
是32位单精度浮点类型,I
是最大正整数。这在浮点类型的范围内,但不能精确地表示为浮点数。其中一些32位用于指数
相反,从整数到浮点的转换取决于实现,但通常通过舍入到最接近的可表示值来完成。该舍入值超出了整数类型的范围。转换回整数失败(更确切地说,这是未定义的行为)。否
有可能是i==std::numeric\u limits::max()
,但i
在F
中不能精确表示
如果要转换的值在可以表示的值范围内,但无法准确表示该值,则它是一个实现定义的下一个较低或较高可表示值的选择
由于可以选择下一个更高的可表示值,因此结果
F(i)
可能不再适用于i
,因此返回的转换将是未定义的行为。否。无论采用何种标准,您都不能期望此转换将返回原始整数。这在数学上没有意义。但是如果你仔细阅读你引用的内容,标准清楚地表明了从int到float转换时精度损失的可能性
假设I型和F型使用相同的位数。I的所有位(可能保存一个存储符号的位)用于指定数字的绝对值。另一方面,在F中,有些位用于指定指数,有些位用于有效位。由于可能的指数,范围将更大。但有效位的精度会更低,因为用于其规范的位更少
作为测试,我打印了
std::numeric_limits<int>::max();
std::numeric_limits<float>::max();
std::numeric_limits::max();
标准::数值限制::最大值();
然后,我将第一个数字转换为浮点数,然后再转换回浮点数。max float的指数是38,max int有10个数字,因此显然float的范围更大。但是在将max int转换为float和back之后,我从2147473647
转换为-2147473648
。所以这个数字似乎增加了一个单位,然后转到了负值
我没有检查我的系统中实际使用了多少位来进行浮点运算,但它至少显示了精度的损失,并且显示gcc“四舍五入”。@vsoftco您必须重新表述这一点
I。假设I
和F
具有相同的大小,比如说32位。然后取最大的整数。它必须将lossily转换为F
类型的值。如果选择的可表示值大于下一个整数,则转换回将导致UB。@KerrekSB,它拒绝了我的评论。有趣的是,我不知道这会发生。但是,是的,这是非常有意义的,因为浮点在增长时精度较低。小的吹毛求疵。“相反,从整数到浮点的转换将舍入到最接近的可表示值。”这是不能保证的。它将是一个相邻的表示,而不是最近的表示。从技术上讲,这不是未定义的行为,而是实现定义的行为(因为它取决于使用中的浮点类型的语义,这些类型是实现定义的)。@Wug它是实现定义的,如果它是未定义的或不是:)另一个挑剔:“该舍入值超出了整数类型的范围。”这也不能保证。@orlp-Edited。从int的转换