c/c++语言开发共享移位负的有符号值是不确定的

我主演原始的JPEG标准( ITU 81 ),特别是图F.12:扩展V中解码值的符号位

作为参考, SLL术语表示: shift left logical operation (参见PDF的第15页)

移位负的有符号值是不确定的

现在着名的libjpeg实现决定以这种方式实现它(非常直接的转录):

 /* * Figure F.12: extend sign bit. * On some machines, a shift and add will be faster than a table lookup. */ #ifdef AVOID_TABLES #define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) #else #define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) static const int extend_test[16] = /* entry n is 2**(n-1) */ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; #endif /* AVOID_TABLES */ 

很明显,转移负面符号值是UB,所以我想知道JPEG标准的原作者在这里实际意味着什么。 JPEG标准是否仅限于二进制补码表示?

    JPEG标准是否仅限于二进制补码表示?

    使用SLL而不是*2的图表,流程图依赖于2的补码实现。

    C,OTOH,不限于2的补码,也不使用某种“2的补码”方式的移位。 没有这个假设,最好编码。 使用无符号类型是很好的第一步。

     // ((-1)<<15) + 1 ((-1u)<<15) + 1 

    需要查看HUFF_EXTEND()应用程序以获得更深入的答案。

    转移负值只是C语言中未定义的行为。 在汇编程序级别上,这种转换非常精细。 逻辑/算术移位左指令将MSB移入进位位,就是这样。 CPU不会以不确定的方式停止并着火。

    话虽这么说,你可以通过将签名号码转换为无符号来躲避UB。 然后,您将只具有实现定义的行为。 例如, (int)(-1u<<1)实际上并没有调用UB,即使这样的代码看起来很有问题。

    安全的方法是对无符号数( uint32_t )执行所有计算,并仅在实际需要时转换为signed。 切勿对签名类型执行任何forms的按位操作。

    我会完全忽略与不使用二进制补码的异国情调/虚构系统的兼容性。 专注于与现实主流计算机的兼容性。

    很明显,移位负数具有与乘以/除以幂2相同的效果 (对于asigned a << n / a >> n )这对于负左操作数从不是未定义的行为,并且为C / C ++定义良好且精确。

    好吧,尽管已经选择了已接受的答案并且已经产生了关于<<>>运算符的讨论量,我将尝试澄清什么是未定义的和什么不是。

    正如标准所说, 如果你试图向左/右移位负数位 (右运算符必须> 0 )或者大于或等于左运算符的大小(以位为单位 ),行为是不确定的。 但这只影响右操作数,而不影响左操作数。

    在尝试获得有关JPEG解码的解释时,只是试着认为JPEG解码使用COSIN转换(对真实矢量定义)对作为有符号量编码的离散实际近似值,或者,它使用有符号整数来评估低精度样本,所以他们从不处理无符号数量(图书馆设计者认为对整数进行操作比对浮点数进行操作要快)。

    注意

    (请注意,使用此方法进行的负向移位会截断到负无穷大,使-1 >> 1变为-1 ,因为-0.5截断为-1而不是0

      以上就是c/c++开发分享移位负的有符号值是不确定的相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/519175.html

      (0)
      上一篇 2020年12月5日
      下一篇 2020年12月5日

      精彩推荐