【问题标题】:Why does (int) float == float.truncate instead of garbage (How does casting actually work?)为什么 (int) float == float.truncate 而不是垃圾(强制转换实际上是如何工作的?)
【发布时间】:2016-02-25 03:50:20
【问题描述】:

继续将这些数据类型理解为原语

(int) char 和 (char) int 是数据的解释。 (int) c 给出该字符的整数值,而 (char) 14 则返回由 14 编码的字符。

我一直将其理解为“内存解析”,因此它只获取该位置的值,然后对其应用类型过滤器。

鉴于浮点存储为某种版本的科学记数法,存储在内存中的应该是整数形式的垃圾。查看此实用程序http://www.h-schmidt.net/FloatConverter/IEEE754.html 似乎整数部分是分开的。

但是,由于它位于内存的较高部分,因此 int 转换如何知道“重新格式化”?编译器是否确定它是一个浮点数并应用特殊处理,或者发生了什么?

【问题讨论】:

  • 不要质疑低级代码。尝试了解编译器的工作原理就像尝试学习二进制:您已经习惯于用更高级的语言来思考,您将一无所获。
  • 这是编译器的工作之一:生成一个真正从整数表示转换为类似(但不可避免地更复杂)float 或double 编码的代码序列。同样,float 和double 之间的转换也不是微不足道的。
  • 鉴于您已将其标记为 C,因此问题标题确实应该固定为更像 C。没有float.truncate,也不能只写(int) float。
  • 是否所有原始类型都为交叉转换处理?
  • @Captain Prinny “所有原始类型都为交叉转换处理?”许多是,但不是全部。例如,double 与 void * 之间没有定义。

标签: c


【解决方案1】:

你对演员表的理解是完全错误的。强制转换只不过是对从一种类型到另一种类型的值转换的显式请求。他们不会重新解释一种类型的表示,就好像它具有不同的类型一样。源代码:

float f = 42.5;
int x;
x = (int)f;

仅指示编译器生成将表达式f 的浮点值截断为整数并将结果存储在对象x 中的代码。

【讨论】:

    【解决方案2】:

    我一直将其理解为“内存解析”,因此它只获取该位置的值,然后对其应用类型过滤器。

    这是一个错误的理解。

    语言指定了基本算术类型之间的转换。在网上查找“常用算术转换”。你会发现很多描述它的链接。对于将浮点类型转换为整数类型,C99 标准是这样说的:

    6.3.1.4 实数浮点数和整数

    1 当实浮点类型的有限值转换为_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为未定义。

    float f = 4.5;
    int i = (int); // i is 4
    
    f = -6.3;
    i = (int)f;    // i is -6
    

    【讨论】:

    • 未定义是否意味着它会做到但你得到垃圾?我假设它是确定性的,但没有用。
    • @CaptainPrinny,根据其定义,未定义的行为意味着任何事情都可能发生。不要期望任何模式。
    • 所以它是不确定的?这让我很吃惊。
    • @CaptainPrinny,是的,它是不确定的。接受它是什么:)
    • @CaptainPrinny - “不可能”转换的一个非常可能的结果是硬件捕获了无效值。可能会终止程序。或者做点别的。
    猜你喜欢
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2011-06-11
    相关资源
    最近更新 更多