当前位置: 首页 > news >正文

数据类型转换中存在的问题分析

隐式类型转换(implicit type conversion)

隐式类型转换(implicit type conversion)包括整型提升(integer promotion)和标准算数转换(usual arithmetic conversions)

遵循较大范围优先规则

1. 整型提升(integer promotion)

C语言规定,表达式中各种小于int长度的整型值(signed/unsigned character/short integer),都必须先转换为int或unsigned int,才能送入CPU取执行运算。因为CPU中的整型运算器(ALU)操作数长度是int字节长度,使用的通用寄存器长度也是。

验证

#include <stdio.h>int main(int argc, char const *argv[])
{char a = 0xb6;short b = 0xb600;int c = 0xb6000000;if (a == 0xb6)printf("a");if (b == 0xb600)printf("b");if (c == 0xb6000000)printf("c");/*最后输出结果为c因为整型提升:a/b整型提升为int类型*/return 0;
}
#include <stdio.h>int main(int argc, char const *argv[])
{char a = 1;printf("%u", sizeof(a));printf("\n");printf("%u", sizeof(+a));   // 单操作符+,一个主要作用就是“整型提升”/*输出:14*/return 0;
}

2. 标准算数转换(usual arithmetic conversions)

当两个不同的类型操作数进行算数运算时,它们会先转换为一种类型,然后进行计算。转换规则通常是**“较大范围”的类型优先**

#include <stdio.h>int main(int argc, char const *argv[])
{int a = -5;unsigned int b = 10;int result = a + b; // a会被转成无符号整数,最终的运算会按照无符号整数的规则进行printf("result: %d\n", result);  // 5return 0;
}

这里为什么输出结果是正确的,原因在于:printf的%d格式符,结果被解释为有符号整数,即 ( 11111111111111111111111111111011 ) 2 + ( 10 ) 10 (1111 1111 1111 1111 1111 1111 1111 1011)_{2}+(10)_{10} (11111111111111111111111111111011)2+(10)10 解释为有符号整数,这个二进制超出unsigned integer表示范围,解释为负数。

-5的原码-5的反码-5的补码
0x0000 00050xFFFF FFFA0xFFFF FFFB

在这里插入图片描述

实例: 有符号和无符号混合运算问题

当不同数据类型进行运算时,编译器会根据转换规则进行隐式类型转换(如:整数和浮点数运算),以确保所有操作数的类型一致。

问题描述:

这里涉及到的是符号扩展问题,即当进行类型转换或位操作时,编译器将原数据的符号位(最高位)扩展到更高位。

#include <stdio.h>int main()
{int a = -1;         // 有符号整数 0xFFFF FFFFunsigned int b = 1; // 无符号整数if (a > b){printf("a > b\n");}else{printf("a <= b\n");}/*输出结果:a > b分析:在a,b进行比较时,a发生了隐式类型转换,转换为unsigned integer-1的计算机表示采用补码(整数采用补码表示):0x1000 0001 // 原码0xFFFF FFFE // 反码0xFFFF FFFF // 补码因此a整型 隐式转换之后的结果为:4,294,967,295*/return 0;
}

解决方案:

#include <stdio.h>int main()
{int a = -1;         // 有符号整数 0xFFFF FFFFunsigned int b = 1; // 无符号整数if (a > (int)b)     // 解决方案{printf("a > b\n");}else{printf("a <= b\n");}/*输出结果:a > b*/return 0;
}

数据类型范围溢出(overflow)

超出了所使用的数据类型所表示的范围,则会出现溢出现象。

img

整型溢出

#include <stdio.h>
#include <limits.h>
#include <cmath>int main(int argc, char const *argv[])
{int max_int = INT_MAX;int result = max_int + 2;printf("int max value: %d\n", max_int);printf("result: %d\n", result);/*输出结果:int max value: 2147483647result: -2147483647*/return 0;
}

浮点数溢出

#include <stdio.h>
#include <float.h>
#include <math.h>int main(int argc, char const *argv[])
{float large_float = FLT_MAX;float overflow_result = large_float * 2.0;printf("large_float: %e\n", large_float);printf("overflow result: %e\n", overflow_result);if (overflow_result == INFINITY){printf("result is Infinity\n");}/*输出结果:large_float: 3.402823e+038overflow result: 1.#INF00e+000result is Infinity*/return 0;
}

实例:

#include <stdio.h>int main(int argc, char const *argv[])
{long long_value = 2147483648;int int_value = (int)long_value;printf("%d\n", int_value);return 0;/*输出:-2147483648*/
}

数据截断(data truncation)

数据截断导致精度的损失:当高精度数据类型转成低精度数据类型时,会出现精度损失。例如:小数部分会直接截断

#include <stdio.h>int main(int argc, char const *argv[])
{float hv = 123.456;int lv = (int)hv;printf("%d\n", lv);  // 123return 0;
}

reference

C++/C implicit conversion

integer promotion


http://www.mrgr.cn/news/31774.html

相关文章:

  • armbian debian 系统安装overlayroot后无法启用
  • Java+Spring Cloud +UniApp 智慧工地源码,用户PC端、移动端数据同步,支持多端展示
  • Windows本地连接远程服务器并创建新用户详细记录
  • 【论文笔记】BEVNeXt: Reviving Dense BEV Frameworks for 3D Object Detection
  • TMS320F28335的定时器中断实验
  • 数据结构-顺序表
  • Linux常用命令(部分学习待继续补充)
  • (undone) 声音信号处理基础知识(2)
  • 【免杀】CS免杀——ps1免杀
  • 继承和多态
  • 聊聊通过阅读书籍类型来判断人
  • 【算法——二分查找】
  • 500元以内头戴式耳机哪款好?盘点500元以内百元宝藏品牌机型推荐
  • 系统架构设计师 - 案例特训专题 - 软件工程篇
  • Leetcode Hot 100刷题记录 -Day18(反转链表)
  • MongoDB在Linux系统中的安装与配置指南
  • 搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(一)-概述
  • sourceTree使用脚本一键push代码到gerrit
  • Python使用总结之FastAPI高级功能探索:数据库集成与依赖注入
  • Redis使用场景 | 建议收藏✨