Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.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++ 如果浮点范围更大,是否始终定义通过浮点的往返行为?_C++_Language Lawyer_C++14_Floating Point Conversion - Fatal编程技术网

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]

  • 浮点类型的prvalue可以转换为整数类型的prvalue。转换截断; 也就是说,小数部分被丢弃。如果无法删除截断的值,则行为未定义 在目标类型中表示。[注:如果目的地类型为
    bool
    ,请参见4.12.-结束注]
  • 整数类型或非范围枚举类型的PR值可以转换为浮点值 点类型。如果可能的话,结果是准确的。如果要转换的值在可以 无法表示,但无法准确表示值,这是一个由实现定义的选项 下一个较低或较高的可表示值。[注:如果无法计算整数值,则会导致精度损失 精确表示为浮动类型的值。-结束注释]如果转换的值在外部 可以表示的值的范围,行为未定义。如果源类型为
    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的转换