基础位是否被“重新解释”为浮点值?或者是否有运行时转换以产生最近的浮点值?
字节顺序是任何平台上的一个因素(即浮点数的字节顺序与整数不同)?
不同的宽度类型如何表现(例如,int to float与int to double)?
语言标准对此类演员/转换的安全性有何保证?通过强制转换,我的意思是static_cast或C风格的演员。
反向浮点转换为int转换(或双转换为int)怎么样?如果浮点数保持较小的幅度值(例如2),那么当解释为int时,位模式是否具有相同的含义?
答案 0 :(得分:11)
基础位是否被“重新解释”为浮点值?
不,该值根据标准中的规则进行转换。
是否有运行时转换以产生最近的浮点值?
是的,有一个运行时转换。
对于浮点 - >整数,该值被截断,前提是源值在整数类型的范围内。如果不是,则行为未定义。至少我认为重要的是源价值,而不是结果。我必须仔细检查才能确定。如果目标类型为char,则边界情况为CHAR_MAX + 0.5
。我认为将它转换为char是未定义的,但正如我所说,我不确定。
对于整数 - >浮点,如果可能,结果是完全相同的值,否则是整数值两侧的两个浮点值之一。不一定更接近两者。
字节顺序是任何平台上的一个因素(即浮点数的字节顺序与整数不同)?
不,永远不会。转换是根据值而非存储表示来定义的。
不同的宽度类型如何表现(例如,int为float而int为double)?
所有重要的是类型的范围和精度。假设32位整数和IEEE 32位浮点数,则int->浮点转换可能不精确。假设64位IEEE双精度,则int-> double转换不可能是不精确的,因为所有int值都可以精确地表示为double。
语言标准对此类演员/转换的安全性有何保证?通过强制转换,我的意思是static_cast或C风格的演员。
如上所述,除了将浮点值转换为整数类型并且该值超出目标类型的范围外,它是安全的。
如果一个浮点数保持一个小幅度值(例如2),当解释为一个int时,位模式是否具有相同的含义?
不,它没有。 IEEE 32位表示为2 0x40000000
。
答案 1 :(得分:6)
供参考,这是ISO-IEC 14882-2003所说的
4.9浮动积分转换
浮点类型的右值可以转换为整数类型的右值。转换截断;也就是说,丢弃小数部分。如果截断的值无法在目标类型中表示,则行为未定义。 [注意:如果目的地类型是`bool,请参见4.12。 ]
整数类型或枚举类型的右值可以转换为浮点类型的右值。如果可能,结果是准确的。否则,它是下一个较低或较高可表示值的实现定义选择。 [注意:如果积分值不能完全表示为浮点类型的值,则会发生精度损失。 ]如果源类型为
bool
,则值false
将转换为零,值true
将转换为一。
参考:What Every Computer Scientist Should Know About Floating-Point Arithmetic
有关快速float
到int
次转化主题的其他非常有价值的参考:
读得好!
答案 2 :(得分:4)
通常有运行时转换,因为位表示通常不兼容(除了二进制0通常都是0和0.0)。 C和C ++标准仅涉及值,而不是表示,并且通常指定合理的行为。请注意,int
通常无法准确表示较大的float
值,而float
无法表示较大的int
值。
因此:
所有转化均按价值计算,而非按位模式。不要担心位模式。
也不要担心字节序,因为这是一个按比例表示的问题。
如果整数值的绝对值很大,则将int
转换为float
会丢失精度;使用double
的可能性较小,因为double
更精确,并且可以表示更多确切的数字。 (细节取决于系统实际使用的表示形式。)
语言定义对位模式一无所知。
从float
转换为int
也是一个值,而不是位模式。精确的浮点2.0将转换为积分2,因为这是实现的设置方式,而不是因为位模式。
答案 3 :(得分:2)
将整数转换为float时,除非处理极大的整数,否则不会丢失任何精度。
当你将float转换为int时,你实际上是在执行floor()操作。所以它只是丢弃小数后的位
有关浮点读取的更多信息:http://www.lahey.com/float.htm
IEEE单精度格式具有24位尾数,8位指数和符号位。英特尔微处理器(如Pentium)中的内部浮点寄存器具有64位尾数,15位指数和一个符号位。这允许以比许多其他实现更少的精度损失执行中间计算。这样做的缺点是,取决于中间值如何保存在寄存器中,看起来相同的计算可能会产生不同的结果。
因此,如果您的整数使用超过24位(不包括隐藏的前导位),那么您可能会在转换中失去一些精度。
答案 4 :(得分:2)
重新解释?术语“重新解释”通常指的是原始记忆的重新解释。当然,不可能将整数值重新解释为浮点值(反之亦然),因为它们的物理表示通常完全不同。
在转换类型时,正在执行运行时转换(而不是重新解释)。转换通常不仅仅是概念性的,它需要实际的运行时间,因为物理表示的差异。源值和目标值的位模式之间没有语言定义的关系。 Endianness也没有任何作用。
将整数值转换为浮点类型时,如果原始值可以由目标类型精确表示,则会准确转换原始值。否则,转换过程将更改该值。
当您将浮点值转换为整数类型时,将简单地丢弃小数部分(即,不是取最近的值,而是将数字舍入为零)。如果结果不适合目标整数类型,则行为未定义。
另请注意,浮点数到整数转换(反之)是标准转换,并且正式要求不进行任何明确的转换。人们有时可能会使用显式强制转换来抑制编译器警告。
答案 5 :(得分:0)
如果您自己转换值,它将被转换(因此在浮点数中 - > int转换3.14变为3)。
但是如果你施放指针,那么你实际上会“重新解释”基础位。所以如果你做这样的事情:
double d = 3.14;
int x = *reinterpret_cast<int *>(&d);
x将具有基于浮点表示的“随机”值。
答案 6 :(得分:0)
将FP转换为整数类型是非常重要的,甚至没有完全定义。
通常,您的FPU实现了从IEEE格式转换为int
的硬件指令。该指令可能采用控制舍入的参数(在硬件中实现)。您的ABI可能指定舍入到最近的偶数。如果您使用的是X86 + SSE,它“可能不会太慢”,但我无法通过一次Google搜索找到引用。
与任何FP一样,有角落案例。如果将无穷大映射到(TYPE)_MAX
会很好,但通常不是这种情况 - int x = INFINITY;
的结果是未定义的。