【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 + 4294967295unsigned int sum = x + y;printf("1 + 4294967295 = %u (0x%x)\n", sum, sum);// 1 - 4294967295unsigned 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 + 1int sum = a + b;printf("2147483647 + 1 = %d (0x%x)\n", sum, sum);// -2147483648 - 1int 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

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

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

相关文章

【开源】基于JAVA的农村物流配送系统

项目编号&#xff1a; S 024 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S024&#xff0c;文末获取源码。} 项目编号&#xff1a;S024&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2…

深度学习18

卷积层 查看每个数据 使用tensorboard查看 池化层 使用数据集进行训练 创建实例&#xff0c;使用tensorboard进行显示 最大池化保留了图片信息&#xff0c;神经网络训练的数据量大大减小&#xff0c;可以加快训练 非线性激活 非线性激活为神经网络加入了一些非线性的特质…

CTFSHOW sqll注入

号过滤绕过 号和不加通配符的 like 是一样的。 还可以使用 < >号来绕过&#xff0c;<> 在mysql中等于! 如果在加一个! 双重否定代表肯定 就是了 空格过滤绕过 /**/ &#xff0c;()&#xff0c;&#xff0c;tab&#xff0c;两个空格 or and xor not 过滤绕过 a…

正点原子linux应用编程——入门篇2

系统信息与系统资源 本章重点学习如何通过Linux系统调用或C库函数获取系统信息&#xff0c;譬如获取系统时间、日期 以及设置系统时间、日期等&#xff1b;除此之外&#xff0c;还会学习Linux系统下的/proc虚拟文件系统&#xff0c;包括/proc 文件系统是什么以及如何从/proc文…

【APUE】进程间通信

目录 一、管道 1.1 匿名管道 1.2 命名管道 二、XSI IPC 2.1 概述 2.2 消息队列 2.2.1 msgget 2.2.2 msgsnd 2.2.3 msgrcv 2.2.4 msgctl 2.2.5 代码示例 2.3 信号量数组 2.3.1 semget 2.3.2 semop 2.3.3 semctl 2.3.4 代码示例 2.3 共享内存 2.3.1 shmget…

selenium已知一个元素定位同级别的另一个元素

1.需求与实际情况 看下图来举例 &#xff08;1&#xff09;需求 想点击test22&#xff08;即序号-第9行&#xff09;这一行中右边的“复制”这一按钮 &#xff08;2&#xff09;实际情况 只能通过id或者class定位到文件名这一列的元素&#xff0c;而操作这一列的元素是不…

零基础可以学编程吗,不懂英语怎么学编程,中文编程工具实例

零基础可以学编程吗&#xff0c;不懂英语怎么学编程&#xff0c;中文编程工具实例 上图是中文编程工具界面、标尺实例。 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#x…

基于单片机体温心率脉搏检测仪系统设计

**单片机设计介绍&#xff0c; 基于单片机体温心率脉搏检测仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机体温心率脉搏检测仪是一种用于检测人体体温、心率和脉搏等基本生理指标的医疗设备。下面是一个简要…

QT 界面切换

先新建一个Widget工程 ui界面设置如下 在添加一个QT设计师界面类 右键点击添加 第二个UI界面设置如下 代码 链接&#xff1a;https://pan.baidu.com/s/1ovDIG2pno9mJ7mMFh2tq3Q 提取码&#xff1a;6q3m –来自百度网盘超级会员V2的分享

python+pytest接口自动化(2)-HTTP协议基础

HTTP协议简介 HTTP 即 HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09;&#xff0c;是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。 设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。HTTP 协议在 OSI 模型…

vue3 + element-plus + ts el-table封装

vue3 element-plus ts el-table封装 博客参考https://blog.csdn.net/weixin_45291937/article/details/125523244 1. 文件位置&#xff08;根据自己的需求&#xff09; 2. 在 custom 文件夹下面 创建 mytable 文件夹 3. 直接上代码 // index.vue<template><div …

Python实现WOA智能鲸鱼优化算法优化XGBoost回归模型(XGBRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…

CloudCompare简单开发

一、概述 CloudCompare如何进行二次开发&#xff1f;_cloudcompare 二次开发-CSDN博客 开发一个功能&#xff0c;在原始CC的基础上添加一个拓展功能&#xff0c;如下&#xff1a; 二、功能开发 1、修改MainWindow.UI 重点是&#xff1a;要编译&#xff0c;不然在mainwindow.…

JAVA进阶之路JVM-2:类加载机制,类的生命周期,类加载过程,类加载时机,类加载器,双亲委派模型,对象创建过程

JVM类加载机制 类加载 ​ 在JVM虚拟机实现规范中&#xff0c;通过ClassLoader类加载把*.class字节码文件&#xff08;文件流&#xff09;加载到内存&#xff0c;并对字节码文件内容进行验证&#xff0c;准备&#xff0c;解析和初始化&#xff0c;最终形成可以被虚拟机直接使用…

点盾云出现“操作失败,错误码1002”如何解决?

在使用点盾云学习看课时&#xff0c;老师会先将视频或者是在线播放链接发给我们&#xff0c;我们通过下载文件的方式或通过直接在线点播的形式来观看&#xff0c;那么在操作的过程中&#xff0c;有时候我们会遇到一些问题&#xff0c;今天以百度网盘中下载的视频文件为例&#…

浙江启用无人机巡山护林模式,火灾扑救效率高

为了保护天然的森林资源&#xff0c;浙江当地林业部门引入了一种创新技术&#xff1a;林业无人机。这些天空中的守护者正在重新定义森林防火和护林工作的方式。 当下正值天气干燥的季节&#xff0c;这些无人机开始了它们的首次大规模任务。它们在指定的林区内自主巡逻&#xff…

B树与B+树的对比

B树&#xff1a; m阶B树的核心特性&#xff1a; 树中每个节点至多有m棵子树&#xff0c;即至多含有m-1个关键字根节点的子树数属于[2, m]&#xff0c;关键字数属于[1, m-1]&#xff0c;其他节点的子树数属于 [ ⌈ m 2 ⌉ , m ] [\lceil \frac{m}{2}\rceil, m] [⌈2m​⌉,m]&am…

excel对号怎么打

对号无论是老师批改作业&#xff0c;还是在标注某些数据的时候都会用到&#xff0c;但这个符号在键盘上是没有的&#xff0c;那么excel对号怎么打出来呢&#xff0c;其实只要使用插入符号功能就可以了。 excel对号怎么打&#xff1a; 第一步&#xff0c;选中想要打出对号的单…

世界共赢电影在行动 ——世界共赢电影签约仪式在京举行

2023年11月23日&#xff0c;秋景冬温的北京&#xff0c;迎来了美国、韩国、俄罗斯、德国、英国、法国、日本、印度、南非、加拿大、巴西、新加坡、印度尼西亚、伊朗、土耳其、马来西亚、越南、意大利、西班牙、波兰、南非、尼日利亚、澳大利亚等23个国家的影视行业代表&#xf…

第二十章总结

创建线程 继承Thread 类 Thread 类时 java.lang 包中的一个类&#xff0c;从类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建立 Thread 实例。 Thread 对象需要一个任务来执行&#xff0c;任务是指线程在启动时执行的工作&#xff0c;start() 方法启动线程&am…