我对标准6.5.4/6中的下列措辞感到困惑:
如果表达式的值以比强制转换命名的类型(6.3.1.8)所需的范围或精度更大的范围或精度表示,则强制转换指定一个转换,即使表达式的类型与命名类型相同,并移除任何额外的范围和精度。
我无法理解的是,如果命名的类型和表达式的类型是相同的,那么表达式的值如何具有额外的范围或精度。
你能提供一个例子来说明这个规则吗?现在看上去有点混乱。
发布于 2019-06-18 01:14:23
标准允许以比表达式类型更高的精度计算浮点;例如:
float f = 1.234f * 5.678f;编译器可以将操作数转换为long double,进行乘法,然后转换回float。这样做的理由是,在许多处理器上,只使用特定的浮点寄存器大小来计算速度更快,而且人们通常不关心获得精度。
在C17 5.2.4.2.2/9中具体说明了这一点:
除了赋值和转换(移除所有额外范围和精度)外,由具有浮动操作数的运算符和受通常算术转换和浮动常量影响的值所产生的值将被计算为一种格式,其范围和精度可能大于该类型所需的范围和精度。使用评估格式的特点是
FLT_EVAL_METHOD的实现定义值:
−1不确定;0只根据类型的范围和精度评估所有操作和常数;1计算浮子型的运算量和常数,双倍于双型的范围和精度,用长双型的范围和精度评价长双运算和常数;2根据长双类型的范围和精度评估所有操作和常量。FLT_EVAL_METHOD的所有其他负值都描述了实现定义的行为。
因此,您可以检查FLT_EVAL_METHOD,以确定编译器是否可以这样做,但您不一定可以自己控制设置。
您引用的文本重申cast操作符将结果转换回强制转换类型,例如:
float f = 1.234f * 5.678f + 9.012f;理论上可以给出比以下更准确的结果:
float f = (float)(1.234f * 5.678f) + 9.012f;https://stackoverflow.com/questions/56640229
复制相似问题