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;
}
相关推荐
小二·16 小时前
Python Web 开发进阶实战:混沌工程初探 —— 主动注入故障,构建高韧性系统
开发语言·前端·python
Lkygo16 小时前
LlamaIndex使用指南
linux·开发语言·python·llama
进阶小白猿16 小时前
Java技术八股学习Day20
java·开发语言·学习
代码村新手16 小时前
C++-类和对象(中)
java·开发语言·c++
葵花楹17 小时前
【JAVA课设】【游戏社交系统】
java·开发语言·游戏
赵谨言17 小时前
Python串口的三相交流电机控制系统研究
大数据·开发语言·经验分享·python
民乐团扒谱机17 小时前
【微实验】数模美赛备赛:多目标优化求解实战(MATLAB实现,以流水车间调度为例)
开发语言·数学建模·matlab·甘特图·遗传算法·多目标优化·优化模型
努力的小陈^O^18 小时前
问题:Spring循环依赖问题排查与解决
java·开发语言·前端
Ccjf酷儿18 小时前
C++语言程序设计 (郑莉)第十章 泛型程序设计与C++标准模板库
开发语言·c++
FreeBuf_18 小时前
利用零宽度字符的隐形JavaScript混淆工具InvisibleJS浮出水面
开发语言·javascript·ecmascript