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

news2025/1/19 3:28:48

本文档包含内容有:

  1. 数据类型转换中的隐式类型转换存在的风险;
    整型提升存在的风险
    标准算数转换存在的风险
  2. 数据类型转换中存在的数据类型范围溢出风险;
  3. 数据类型转换中存在的数据精度问题(数据截断)。

隐式类型转换(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字节长度,使用的通用寄存器长度也是。

C语言之父 丹尼斯·里奇与肯·汤普逊 制定的整型提升规则:

“A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion.”

验证

验证是否存在整型提升

#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));   // 单操作符+,一个主要作用就是“整型提升”
    /*
    输出:
    1
    4
    */
    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);  // 5
    return 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

在这里插入图片描述

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

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

问题描述:

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

#include <stdio.h>

int main()
{
    int a = -1;         // 有符号整数 0xFFFF FFFF
    unsigned 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 FFFF
    unsigned int b = 1; // 无符号整数

    if (a > (int)b)     // 解决方案
    {
        printf("a > b\n");
    }
    else
    {
        printf("a <= b\n");
    }
    /*
    输出结果:a > b
    */
    return 0;
}

实例2

和实例1对隐式类型转换的解决方法一致
C++隐式类型转换问题

数据类型范围溢出(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: 2147483647
    result: -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+038
    overflow result: 1.#INF00e+000
    result 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);  // 123
    return 0;
}

reference

C++/C implicit conversion

integer promotion

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2154030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

此框架你到底了解多少???

1.简述对Spring中IOC/DI的理解 IOC&#xff1a;控制反转&#xff0c;将创建和管理的对象的任务交给外部的Spring容器 DI&#xff1a;依赖注入&#xff0c;对象之间存在依赖关系&#xff0c;创建对象时&#xff0c;对其依赖的对应直接进行赋值 2.有哪些依赖注入的方式 基于注…

【计算机网络】详解UDP套接字网络字节序IP地址端口号

一、网络字节序 我们已经知道, 内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出; 接收主机把从网络上接到…

软考中级软设背诵内容

冯诺依曼结构、哈佛结构 冯诺依曼结构: 程序指令和数据都采用二进制表示 程序指令和数据在同一个存储器中混合 程序的功能都由中央处理器&#xff08;CPU&#xff09;执行指令来实现 程序的执行工作由指令进行自动控制 SRAM、DRAM 与DRAM相比&#xff0c;SRAM集成率低、功…

页面布局实现-左侧横向滑动展示隐藏数据,右侧固定展示操作按钮。可上下滑动联动

效果图 1.布局排版 <LinearLayoutandroid:layout_width"match_parent"android:layout_height"match_parent"android:orientation"vertical"android:padding"1dp"><LinearLayoutandroid:id"id/lltList"android:lay…

Java:Clonable 接口和拷贝

一 Clonable 接口 在 Java SE 中&#xff0c;Cloneable 是一个标记接口&#xff08;Marker Interface&#xff09;&#xff0c;它位于 java.lang 包中。这个接口的主要目的是标识实现该接口的类能够被合法地克隆&#xff08;即可以调用 Object 类中的 clone() 方法&#xff09…

Electron应用程序打包后运行报错cannot find module ‘@vue/cli-service‘

本项目打包运行后报错问题的解决办法&#xff0c;类似于其他cannot find module XXX’的报错&#xff0c;也基本可以解决 文章目录 electron应用程序打包后运行报错排查问题解决办法 electron应用程序打包后运行报错 错误如下&#xff1a; 提示找不到该模块 排查问题 本项…

互联网广告产品基础知识

一 计价与效果 广告产品如何估算收入&#xff1f; 一种是从需求侧计算&#xff1a;按照广告主数量进行拟合&#xff1b;一种是从供给侧计算&#xff1a;按照曝光量和千次曝光单价进行拟合。 需求侧 从需求侧&#xff0c;也就是广告主侧&#xff0c;来计算广告产品的总收入&…

Linux命令:用于创建新的用户组的命令行工具groupadd 详解

目录 一、概述 二、组标识符GID 1、定义 &#xff08;1&#xff09;标识符 &#xff08;2&#xff09;与UID的关系 2、GID的作用 &#xff08;1&#xff09;用户组管理 &#xff08;2&#xff09;文件权限控制 &#xff08;3&#xff09;用户权限管理 &#xff08;4&…

threejs性能优化之gltf文件压缩threejs性能优化之glb文件压缩

在使用Three.js进行3D图形开发时&#xff0c;GLTF&#xff08;GL Transmission Format&#xff09;文件因其高效性和灵活性而广受欢迎。然而&#xff0c;随着模型复杂度的增加&#xff0c;GLTF文件的大小也会显著增加&#xff0c;这可能会对加载时间和渲染性能产生负面影响。为…

插入与冒泡排序(C++)

\一、插入排序 1 简介 插入排序&#xff0c;也称为直接插入排序&#xff0c;其排序思想和我们平时打扑克牌时排序类似。 2 算法步骤 将第一个元素看作已排序序列&#xff0c;第二个到最后一个看作未排序序列。 第二个元素&#xff0c;与之前已排序号的序列进行对比&#x…

【我的 PWN 学习手札】tcache stash with fastbin double free —— tcache key 绕过

参考看雪课程&#xff1a;PWN 探索篇 前言 tcache key 的引入使得 tcache dup 利用出现了困难。除了简单利用 UAF 覆写 key 或者House Of Karui 之外&#xff0c;还可以利用 ptmalloc 中的其他机制进行绕过。 一、Tcache Stash with Fastbin Double Free 之前是 double free …

软考中级软件设计师——知识产权学习记录

软考中级软件设计师——知识产权 著作权人身权著作财产权著作权侵权行为 计算机软件著作权基本知识计算机软件著作权侵权 专利地域性与专利权申请基本知识专利权侵权 职务作品委托开发商业秘密权基本知识商业秘密侵权 商标权与商标注册基本知识商标权侵权 著作权 著作权也称为…

Spring的任务调度

Spring的任务调度 1.概述 Spring框架为任务调度提供了专门的解决方案。在Spring框架的org.springframework.scheduling包中&#xff0c;通过对JDK 的ScheduledExecutorService接口的实例进行封装&#xff0c;对外提供了一些注解和接口&#xff0c;为开发者处理定时任务提供了…

网安面试会问到的:http的长连接和短连接

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

探索 Python 的火焰:Fire 库的神秘力量

文章目录 &#x1f525; 探索 Python 的火焰&#xff1a;Fire 库的神秘力量第一部分&#xff1a;背景介绍第二部分&#xff1a;Fire 库是什么&#xff1f;第三部分&#xff1a;如何安装 Fire&#xff1f;第四部分&#xff1a;简单库函数使用方法第五部分&#xff1a;场景应用第…

32.递归、搜索、回溯之floodfill算法

0.简介 1.图像渲染 . - 力扣&#xff08;LeetCode&#xff09; 题目解析 算法原理 代码 class Solution {int[] dx { 0, 0, 1, -1 };int[] dy { 1, -1, 0, 0 };int m, n;int prev;public int[][] floodFill(int[][] image, int sr, int sc, int color) {if (image[sr][sc]…

yolov5足球运动分析-速度分析-足球跟踪

足球分析项目 引言 在现代体育分析领域&#xff0c;利用先进的计算机视觉技术和机器学习模型对比赛视频进行深入解析已成为一种趋势。本项目旨在通过YOLO&#xff08;You Only Look Once&#xff09;这一顶级的人工智能目标检测模型来识别并跟踪足球比赛中的球员、裁判以及足球…

【每日一题】LeetCode 2374.边积分最高节点(图、哈希表)

【每日一题】LeetCode 2374.边积分最高节点&#xff08;图、哈希表&#xff09; 题目描述 给定一个有向图&#xff0c;图中包含 n 个节点&#xff0c;节点编号从 0 到 n - 1。每个节点都有一个出边&#xff0c;指向图中的另一个节点。图由一个长度为 n 的整数数组 edges 表示…

江协科技STM32学习- P15 TIM输出比较

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

6张图掌握提示词工程师工作范围与工作技巧(提示词原理篇)

在人工智能的疆域中&#xff0c;提示词工程师扮演着至关重要的角色。他们精心设计的话语&#xff0c;是引导AI模型理解人类需求、激发创造力的关键。如同指挥官的号令&#xff0c;提示词工程师的每一个提问&#xff0c;都让AI的潜力得到释放&#xff0c;让技术与智慧的对话更加…