【C语言】深入理解数据类型转换与运算

文章目录

  • 1.数据类型转换
      • 在分析源程序之前,我们需要了解几个基本概念:
      • 现在来分析源程序中的变量及其对应的十进制真值以及扩展操作方式:
    • 1.1. `short si = -32768;`
    • 1.2. `unsigned short usi = si;`
    • 1.3. `int i = si;`
    • 1.4. `unsigned ui = usi;`
  • 2.编写程序说明不同数据类型之间进行转换时在表数范围和精度上的变化。
    • 2.1. 给定一个`short`型数据 `-12345`,分别转换为`int、unsigned short、unsigned int、float`类型的数据;
    • 2.2. 给定一个`int`型数据`2147483647`,分别转换为`short、unsigned short、unsigned int、float、double`类型的数据;
    • 2.3.给定一个`float`型数据`123456.789e5`,转换成`int、double`型数据;
    • 2.4.给定一个`double`型数据`123456.789e5`,转换成`int、float`型数据。`#include <stdio.h>`
    • 根据实验结果,回答下列问题:
      • (1)补码整数(如`int`型数)是否总能转换为等值的`float`类型数据?为什么?
      • (2)`float`型数据是否总能转换成等值的`double`型数据?为什么?
      • (3)长数被截断成短数后可能发生什么现象?为什么?
  • 3.编程计算下列表达式的值:
    • 3.1. unsigned int型数据: 1+4294967295=?;1-4294967295=?
    • 3.2. int型数据:2147483647+1=?;-2147483648-1=?

在程序设计中,数据类型转换和运算溢出是一个常见但也容易被忽视的问题。本文通过具体的代码示例,深入分析了不同数据类型之间的转换及在运算过程中可能出现的溢出现象,旨在帮助读者更加深入地理解这些概念。

1.数据类型转换

让我们首先来分析,下列源程序中的变量在机器内是如何表示的,以及各变量对应的十进制真值是多少,无符号数和带符号整数的扩展操作方式是否相同?各是如何进行的?

#include <stdio.h>
int main()
{
    short si = -32768;
    unsigned short usi = si;
    int i = si;
    unsigned ui = usi;
    printf("%d\n", si);
    printf("%u\n", usi);
    printf("%d\n", i);
    printf("%u\n", ui);
    return 0;
}

在这里插入图片描述

在分析源程序之前,我们需要了解几个基本概念:

  1. 有符号整数:以补码形式存储,最高位为符号位,0表示正数,1表示负数。
  2. 无符号整数:以二进制形式存储,没有符号位,全部位都用于表示数值。

现在来分析源程序中的变量及其对应的十进制真值以及扩展操作方式:

在这里插入图片描述

1.1. short si = -32768;

在这里插入图片描述
si 是一个有符号短整型变量,占用2个字节(16位)。
十进制真值-32768
扩展操作方式:将-32768直接存储到 si 中,不需要进行扩展操作。

1.2. unsigned short usi = si;

在这里插入图片描述

usi 是一个无符号短整型变量,占用2个字节(16位)。
十进制真值32768
扩展操作方式:将 si 的二进制补码表示直接转换为无符号数的二进制表示。

1.3. int i = si;

在这里插入图片描述

i 是一个有符号整型变量,占用4个字节(32位)。
十进制真值-32768
扩展操作方式:由于 si 是一个有符号短整型变量,它的扩展操作是将其符号位扩展到更高位,即复制符号位,直到填满 i 的所有位。

1.4. unsigned ui = usi;

在这里插入图片描述

ui 是一个无符号整型变量,占用4个字节(32位)。
十进制真值32768
扩展操作方式:将 usi 的二进制表示直接转换为无符号整数的二进制表示。
综上所述,无符号数和带符号整数的扩展操作方式是不同的。无符号数直接将二进制表示转换为目标类型,而带符号整数需要进行符号位的扩展操作。

2.编写程序说明不同数据类型之间进行转换时在表数范围和精度上的变化。

2.1. 给定一个short型数据 -12345,分别转换为int、unsigned short、unsigned int、float类型的数据;

#include <stdio.h>
int main() {
    short s = -12345;
    int i = s;
    printf("s as int: %d\n", i);
    unsigned short us = (unsigned short)s;
    printf("s as unsigned short: %u\n", us);
    unsigned int ui = (unsigned int)s;
    printf("s as unsigned int: %u\n", ui);
    float f = (float)s;
    printf("s as float: %f\n", f);
    return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

由于short类型是有符号的,而unsigned shortunsigned int都是无符号的,因此s转换为unsigned shortunsigned int时会被解释为一个很大的正整数

在进行float类型的转换时,系统会将short类型的值转换为float类型的值,并在其末尾添加一些额外的零,以使其符合float类型的规格化格式。

2.2. 给定一个int型数据2147483647,分别转换为short、unsigned short、unsigned int、float、double类型的数据;

#include <stdio.h>
int main() {
    int i = 2147483647;
    short s = (short)i;
    printf("i as short: %d\n", s);
    unsigned short us = (unsigned short)i;
    printf("i as unsigned short: %u\n", us);
    unsigned int ui = (unsigned int)i;
    printf("i as unsigned int: %u\n", ui);
    float f = (float)i;
    printf("i as float: %f\n", f);
    double d = (double)i;
    printf("i as double: %lf\n", d);
    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在32位系统中,int类型占据4个字节,范围为-21474836482147483647
当将最大值2147483647转换为short类型时,超出了short类型的范围,导致截断,结果为-1
当将最大值2147483647转换为unsigned short类型时,超出了unsigned short类型的范围,结果为65535
当将最大值2147483647转换为unsigned int类型时,结果仍然是2147483647,因为unsigned int类型足够存储这个数值。
当将最大值2147483647转换为float类型时,由于float类型的精度限制,整数部分超过了可表示的范围,结果变为2147483648.000000
当将最大值2147483647转换为double类型时,double类型的精度比float更高,能够保持原始值。

2.3.给定一个float型数据123456.789e5,转换成int、double型数据;

#include <stdio.h>
int main() {
    float f = 123456.789e5;
    int i = (int)f;
    printf("f as int: %d\n", i);
    double d = (double)f;
    printf("f as double: %lf\n", d);
    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在32位机器上,int类型占据4个字节,范围为-21474836482147483647。而变量f的值为123456.789e5,即123456.789乘以105次方,结果为12345678900
当将float类型的变量f转换为int类型时,会发生截断操作。由于整数部分超过了int类型的范围,截断结果为-2147483648,即int类型的最小值。
当将float类型的变量f转换为double类型时,由于double类型的精度比float更高,能够准确表示变量f的值。因此,结果为12345679104.000000

2.4.给定一个double型数据123456.789e5,转换成int、float型数据。#include <stdio.h>

int main() {
    double d = 123456.789e5;
    int i = (int)d;
    printf("d as int: %d\n", i);
    float f = (float)d;
    printf("d as float: %f\n", f);
    return 0;
}

在这里插入图片描述
在这里插入图片描述
在32位机器上,int类型占据4个字节,范围为-21474836482147483647。而变量d的值为123456.789e5,即123456.789乘以105次方,结果为12345678900
当将double类型的变量d转换为int类型时,会发生截断操作。由于整数部分超过了int类型的范围,截断结果为2147483647,即int类型的最大值。
当将double类型的变量d转换为float类型时,由于float类型的精度较低,无法完全保留double类型的精度。因此,结果为12345679232.000000,存在舍入误差。

根据实验结果,回答下列问题:

(1)补码整数(如int型数)是否总能转换为等值的float类型数据?为什么?

补码整数(如int型数)并不总能转换为等值的float类型数据。这是因为在转换过程中,如果整数部分过大或者过小,超出了float类型能表示的范围,就会发生精度丢失或者溢出的情况。例如,在32位机器上,int类型范围为-21474836482147483647,而float类型的有效范围约为±3.4e±38,当int型数据超出了这个范围时,就无法准确表示为对应的float类型数据。

(2)float型数据是否总能转换成等值的double型数据?为什么?

float型数据并不总能转换成等值的double型数据。虽然float和double都表示浮点数,但是double类型具有更高的精度和表示范围。因此,当一个float类型数据转换为double类型时,会出现精度损失的情况,因为double类型无法准确表示所有的float类型数据,特别是对于较大或较小的浮点数。

(3)长数被截断成短数后可能发生什么现象?为什么?

将长数截断为短数后,可能发生精度丢失或溢出的现象。例如,将一个较大的double类型数据截断为float类型,或者将一个int类型数据赋给short类型变量,都可能导致数据溢出或者精度丢失。这是因为短数类型能够表示的范围和精度比长数类型更小,所以超出范围的部分会被截断或者舍入,导致数据的改变。

3.编程计算下列表达式的值:

3.1. unsigned int型数据: 1+4294967295=?;1-4294967295=?

#include <stdio.h>

int main() {
    unsigned int x = 1;
    unsigned int y = 4294967295;

    // 1 + 4294967295
    unsigned int sum = x + y;
    printf("1 + 4294967295 = %u (0x%x)\n", sum, sum);

    // 1 - 4294967295
    unsigned int diff = x - y;
    printf("1 - 4294967295 = %u (0x%x)\n", diff, diff);

    return 0;
}

在这里插入图片描述

  • 对于第一个表达式,unsigned int类型的数据是无符号数,范围为04294967295。由于1加上4294967295等于4294967296,超出了unsigned int类型的表示范围,因此结果为0。对于无符号数来说,溢出后会自动回绕,即4294967296等于0
  • 对于第二个表达式,1减去4294967295的结果为2。同样地,由于unsigned int类型是循环的,4294967295减去1实际上等于2。

3.2. int型数据:2147483647+1=?;-2147483648-1=?

#include <stdio.h>

int main() {
    int a = 2147483647;
    int b = 1;
    int c = -2147483648;
    int d = -1;

    // 2147483647 + 1
    int sum = a + b;
    printf("2147483647 + 1 = %d (0x%x)\n", sum, sum);

    // -2147483648 - 1
    int diff = c - d;
    printf("-2147483648 - 1 = %d (0x%x)\n", diff, diff);

    return 0;
}

在这里插入图片描述

  • 对于第一个表达式,int类型的数据是有符号数,范围为-21474836482147483647。由于2147483647加上1等于2147483648,超出了int类型的表示范围,因此结果为-2147483648。这是因为在有符号整数中,溢出会导致“环绕”现象。
  • 对于第二个表达式,-2147483648减去1的结果为2147483647。由于-1的补码为0xffffffff,将-2147483648减去1相当于对-2147483648取反后加1,得到的就是2147483647

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

U-Net及其变体在医学图像分割中的应用研究综述

U-Net及其变体在医学图像分割中的应用研究综述 论文来自&#xff1a;中国生物医学工程学报 2022 摘 要&#xff1a; 医学图像分割可以为临床诊疗和病理学研究提供可靠的依据&#xff0c;并能辅助医生对病人的病情做出准确的判断。 基于深度学习的分割网络的出现解决了传统自动分…

Git——Git应用入门

将会介绍以下知识&#xff1a; 搭建Git环境和创建Git版本库&#xff08;init、clone&#xff09;。文件添加、状态检查、创建注释和查看历史记录。与其他Git版本库交互&#xff08;pull、push&#xff09;。解决合并冲突。创建分支列表、列表切换和合并。创建标签。 1、版本控…

sqli-labs靶场详解(less17-less22)

目录 less-17 less-18 less-19 less-20 less-21 less-22 less-17 修改密码关卡 服务器后端 账号密码都存在数据库中 使用UPDATE进行修改密码 尝试username处 尝试好久尝试不出来应该是对用户名进行了过滤 于是对password进行注入 判断注入点 passwdadmin 报错&#xff1a…

vue3中的customRef创建一个自定义的 ref对象

customRef 创建一个自定义的 ref&#xff0c;并对其依赖项跟踪和更新触发进行显式控制 小案例: 自定义 ref 实现 debounce <template><div style"font-size: 14px;"><input v-model"text" placeholder"搜索关键字"/><…

智能优化算法应用:基于郊狼算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于郊狼算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于郊狼算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.郊狼算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

深思:C与C++相互调用问题

背景 上周&#xff0c;偶然看到同事愁眉苦脸的样子&#xff0c;便善意咨询了下发生了什么。简单沟通下&#xff0c;才知道他遇到了一个工程编译的问题&#xff0c;一直无法编译通过&#xff0c;困扰了他快一天时间。出于个人的求知欲和知识的渴望&#xff0c;我便主动与他一同分…

PHP中关于func_get_args()方法

首先呢这个函数出现的是比较早的,大致应该是PHP4出现的, func_get_args — 返回一个包含函数参数列表的数组 说明 func_get_args(): array 获取函数参数列表的数组。 该函数可以配合 func_get_arg() 和 func_num_args() 一起使用&#xff0c;从而使得用户自定义函数可以接…

基于C#实现块状链表

在数据结构的世界里&#xff0c;我们会认识各种各样的数据结构&#xff0c;每一种数据结构都能解决相应领域的问题&#xff0c;当然每个数据结构&#xff0c;有他的优点&#xff0c;必然就有它的缺点&#xff0c;那么如何创造一种数据结构来将某两种数据结构进行扬长避短&#…

【数据结构/C++】栈和队列_循环队列

牺牲一个存储单元来判断队满。 #include<iostream> using namespace std; // 循环队列 #define MaxSize 10 typedef int ElemType; typedef struct {ElemType data[MaxSize];int front, rear; } SqQueue; // 初始化队列 void InitQueue(SqQueue &Q) {// 判断队空 Q.…

微服务知识大杂烩

1.什么是微服务? 微服务(Microservices)是一种软件架构风格,将一个大型应用程序划分为一组小型、自治且松耦合的服务。每个微服务负责执行特定的业务功能,并通过轻量级通信机制(如HTTP)相互协作。每个微服务可以独立开发、部署和扩展,使得应用程序更加灵活、可伸缩和可…

Milvus入门手册1.0

一、window环境搭建&#xff08;单机&#xff09; 1、docker安装 略 2、milvus安装 参考文档&#xff1a;https://milvus.io/docs/install_standalone-docker.md tips: &#xff08;1&#xff09;compose.yaml下载比较慢&#xff0c;可以在网络上找一份。 &#xff08;2&…

2023-11-26 LeetCode每日一题(统计子串中的唯一字符)

2023-11-26每日一题 一、题目编号 828. 统计子串中的唯一字符二、题目链接 点击跳转到题目位置 三、题目描述 我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符&#xff0c;并返回唯一字符的个数。 例如&#xff1a;s “LEETCODE” &#xff0c;则其…

Python字典合并

合并两个有部分key相同的字典&#xff0c;相同key保留两个字典中对应key的较大值。 (笔记模板由python脚本于2023年11月27日 18:12:15创建&#xff0c;本篇笔记适合熟悉Python字典的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Fr…

通过预定义颜色查找表上色_vtkLookupTable_vtkColorTransferFunction

开发环境&#xff1a; Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example demo解决问题&#xff1a;通过颜色查找表给vtkPlaneSource上色 第一种技术是使用预定义颜色的查找表vtkLookupTable。这包括创建一个查找表并为其分配一组已命名的…

攻关眼科难题!第一届爱尔眼科-四川大学科研基金完成立项

当前我国眼科患者数量不断增长&#xff0c;人民群众对高质量的眼健康的需要不断攀升&#xff0c;而目前国内眼科医疗资源远不能满足需求&#xff0c;疑难眼病诊疗能力及学术科研体系建设仍有较大进步空间。基于此&#xff0c;爱尔眼科携手四川大学共同设立爱尔眼科-四川大学科研…

js moment时间范围拿到中间间隔时间

2023.11.27今天我学习了如何对只返回的开始时间和结束时间做处理&#xff0c;比如后端返回了&#xff1a; [time:{start:202301,end:202311}] 我们需要把中间的间隔渲染出来。 [202301,202302,202303,202304,202305,202306,202307,202308,202309,202310,202311] 利用moment…

搭建你自己的网盘-个人云存储的终极解决方案-nextcloud AIO(二)

今天接着上篇&#xff0c;我们继续来玩nextcloud AIO. 当我们看到这个页面的时候&#xff0c;则证明AIO已经安装好了&#xff0c;登录账号和密码在图上已经标注了。点击open your nextcloud 即可跳转到我们的域名的登录页。 输入用户名和密码后登录即可。 打开前台页面&#x…

【Dockerfile】将自己的项目构建成镜像部署运行

目录 1.Dockerfile 2.镜像结构 3.Dockerfile语法 4.构建Java项目 5.基于Java8构建项目 1.Dockerfile 常见的镜像在DockerHub就能找到&#xff0c;但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像&#xff0c;就必须先了解镜像的结构才行。 2.镜像结构 镜…

element table滚动条失效

问题描述:给el-table限制高度之后滚动条没了 给看看咋设置的&#xff1a; <el-table:data"tableData"style"width: 100%;"ref"table"max-height"400"sort-change"changeSort">对比了老半天找不出问题&#xff0c;最后…

上门预约互联网干洗店洗鞋店小程序开发

很多时候可能大家的衣服鞋子需要干洗&#xff0c;但又不想出门送去店里&#xff0c;大家就可以使用手机线上下单预约取货&#xff0c;会有专门的人上门来取衣服&#xff0c;让你能够轻松的进行洗护。 闪站侠洗衣洗鞋小程序&#xff0c;提供了足不出户就能预约人员上门去 衣送洗…