【问题标题】:How to interpret an unsigned integer as a signed one and vice versa in Crystal?如何在 Crystal 中将无符号整数解释为有符号整数,反之亦然?
【发布时间】:2020-12-15 14:27:43
【问题描述】:

在 C 中,要将整数的位解释为另一种类型的整数(不是强制转换整数,而是将相同的位用于不同的类型),可以这样做:

uint8_t x = 0xFF;
int8_t y = *((int8_t*) &x);

我在 Crystal 中能想到的最好的就是这个,但它非常不安全,而且 y 的寿命与 x 一样长(事实上,你不能重复使用相同的变量)。

x = 0xFF_u8
y = pointerof(x).as(Int8*).value

有没有一种惯用且安全的方式在 Crystal 中进行这种转换?我不介意复制的值。

(是的,你敢肯定我正在用 Crystal 编写模拟器!)

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    您可以使用unsafe_as,例如:

    x = 0xFF_u8            # 255 : Uint8
    y = x.unsafe_as(Int8)  # -1  : Int8
    

    但顾名思义,使用时要小心。引用文档:

    此方法是不安全的,因为当给定类型的字节大小与接收方不同,或者给定类型表示在语义上与底层字节不匹配时,它的行为不可预测。

    如果你想检测过载,首选to_i8

    x = 0xFF_u8
    z = x.to_i8 # Arithmetic overflow
    

    您必须确定第一个版本对于您的用例是否足够安全。虽然您问题中的 C 代码可能不是未定义的行为,但它应该是依赖于实现的行为。这意味着,它在严格意义上是不可移植的,但您应该为特定架构获得一致的结果。鉴于two's-complement 现在实际上是一个标准,我希望在当今的大多数硬件上看到相同的行为。 Crystal 代码应该属于同一类。

    【讨论】:

      猜你喜欢
      • 2011-10-14
      • 2019-07-23
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-21
      • 1970-01-01
      • 2014-01-13
      相关资源
      最近更新 更多