c语言赋值截断

目录

截断含义

截断举例


截断含义

在C语言中,将一个较宽范围的整型(如16位的short或int16_t)赋值给一个较窄范围的整型(如8位的char或int8_t)时,如果原值超出了目标类型的表示范围,就会发生所谓的"截断"(truncation)。这意味着,超出的部分会被丢弃,只保留目标类型能够表示的部分。

注意截断指的是存储在内存中补码进行截断。数值的存储都是以补码存储在内存中。

截断举例

以无符号16位整型 赋值给 无符号整型8位为例,8位整型的范围是0-255,16位整型的范围是0-65536。要看到截断的效果,可以选择一个大于255(即8位无符号整型的最大值)但小于65536(16位无符号整型的最大值)的数。比如uint16_t类型的300赋值给uint8_t类型。选择300(二进制表示为0000 0001 0010 1100),那么截断后,将只保留低8位0010 1100,这对应于十进制的44。


再比如int16_t的130赋值给int8_t类型。int8_t类型只能表示-128到127之间的整数。int16_t范围在-32768到32767。130的二进制补码表示(在int16_t中)是0000 0000 1000 0010。但是,当将其赋值给int8_t时,只有低8位被保留,即1000 0010。

由于int8_t类型是有符号类型,首位1看作符号位,为负数。根据二进制补码的规则,要计算这个数的实际值,需要先取反(不包括最高位)然后加1,可以得到为-126。

更简单的方法就是忽略符号位(即最高位),剩下的7位是000 0010,这是2的二进制表示。但是,由于整个数是负数,在二进制补码系统中,这是通过从-128(1000 0000)开始加上这个正数来完成的,即-126。此外,如果相加后的值超过了127(int8_t得最大值),可由循环得到最终的值,比如相加后的值为128那么最终就是-128,因为127的下一个值是-128。

cpp 复制代码
#include <stdio.h>

int main(void)
{
    uint16_t wideVar = 300; // unsigned short
    uint8_t narrowVar = (uint8_t)wideVar; // unsigned char
    printf("%u, %u\n", wideVar, narrowVar); // 300, 44

    int16_t wideVar2 = 130;  // signed short
    int8_t narrowVar2 = (int8_t)wideVar2; // signed char
    printf("%d, %d\n", wideVar2, narrowVar2); // 130, -126

    return 0;
}
相关推荐
赴生-7 小时前
C++进阶 C++11(下)
开发语言·c++
赴生-8 小时前
C++进阶 异常
开发语言·c++
黄毛火烧雪下8 小时前
Java 核心知识点总结(一)
java·开发语言
其实防守也摸鱼9 小时前
软件安全与漏洞--软件安全编码与防御技术理论题库
开发语言·网络·安全·网络安全·软件安全·软件安全与漏洞
x138702859579 小时前
c语言中srtlen(指针使用计算字符长度)、传值和传址调用
c语言·开发语言·算法·visual studio
iCxhust9 小时前
C#进程管理程序
开发语言·汇编·stm32·单片机·c#·微机原理
凡人叶枫9 小时前
Effective C++ 条款28:避免使用 handles 指向对象内部
linux·服务器·开发语言·c++·嵌入式开发
努力成为AK大王9 小时前
并发编程的核心挑战、优化方案与核心知识点总结
java·开发语言·数据库
AI 编程助手GPT10 小时前
用 Python 做一个世界杯赛前分析脚本:以巴西 vs 摩洛哥为例
开发语言·网络·人工智能·python·chatgpt
lihao lihao10 小时前
Linux信号
开发语言·c++·算法