类型转换

需了解整形和浮点型之间的类型转换,以及不同长度的类型之间的转换,可能在选择题考察,也会在大题中作为知识点考察。

有符号整数和无符号整数

有符号整数无符号整数 之间相互转换时,二进制数据 不变,只是改变了变量(或数字)的类型。

首先需要了解 有符号整数(int)和 无符号整数(unsigned)这两个类型:

  • int:使用 补码 来存储数据。
  • unsigned:所有位,包括最高位,都用于表示数值,表示非负数。
注意

在现在的 64 位计算机中,一般 int 表示 32 位 有符号整数unsigned 表示 32 位 无符号整数
由于 intunsigned 在不同体系计算机中行为不同,所以 C 语言库中也自带 int32_tuint32_t 这种类型来表示特定位数的 有符号无符号 整数,并在各计算中行为一致。

这里为了方便说明,以 8 位 有符号整数无符号整数 为例:

  • 8 位 有符号整数
    • 表示的范围为 -128 ~ 127
    • 最大数为127,对应的二进制为0111 1111
    • 最小数为-128,对应的二进制为1000 0000
  • 8 位 无符号整数
    • 表示的范围为 0 ~ 255
    • 最大数为255,对应的二进制为1111 1111
    • 最小数为0,对应的二进制为0000 0000

intunsigned 进行 类型转化 时,位模式 不变,可以理解成计算机存储单元中的二进制表示没有变化,只是从程序层面阐述该二进制数据的方式变了,如下图所示:

SignedUnsignedConversioncluster_signed有符号整数 (int8)cluster_unsigned无符号整数 (uint8)s_min-128(1000 0000)u_128128(1000 0000)s_min->u_128位模式相同1000 0000s_minus1-1(1111 1111)u_255255(1111 1111)s_minus1->u_255位模式相同1111 1111s_zero0(0000 0000)u_min0(0000 0000)s_zero->u_min位模式相同0000 0000s_max127(0111 1111)u_127127(0111 1111)s_max->u_127位模式相同0111 1111

整形和浮点数

在计算机中,整形(short, int, long)和 浮点数(float, double)之间可以相互转换,但是在转换的过程中可能出现 精度丢失数据溢出

整形转浮点数

如果一个整数被转换为浮点数,其结果是否会产生 精度丢失 取决于整数的大小是否超过浮点数可以精确表示的整数范围。
但当整数足够大时,转换可能导致 精度损失

比如对于 float 类型,其尾数为 23 位,它可以精确表示的整数范围为 $(-2^{24}, 2^{24})$,如果一个 int 类型的数字在这个范围内,则将其转换为 float不会丢失精度

但是如果 int 类型数字超出这个范围且低 8 位不全为 0 的话,则将其转换为 float 会有 精度丢失

浮点数转整数

浮点数 被转换为 整数 时,小数部分会丢失,因为 整数 不能表示小数。

此外,如果 浮点数 超出了 整形 的表示范围,转换可能会 溢出 或产生未定义行为(取决于语言)。

不同长度的类型转换

类型最小位数常见位数(32 位系统)常见位数(64 位系统)
char8 位8 位8 位
short16 位16 位16 位
int16 位32 位32 位
long32 位32 位64 位
long long64 位64 位64 位
float-32 位32 位
double-64 位64 位

总结一下不同长度的 整数浮点数类型转换 规则:

  • 整数和整数
    • 较小的 整数类型 被转换为较大的 整数类型 时,高位会被自动填充为 0 或 1,不会有数据丢失。
    • 较大的 整数类型 被转换为较小的 整数类型 时,高位会被自动截断,可能有数据丢失。
  • 浮点数和浮点数
    • float 转为 double 时,不会有 精度丢失double 转为 float 时,可能有 精度丢失
Higher Data Type
float
long
int
short
char
unsigned
Lower Data Type
没有
精度丢失
可能有
精度丢失
long long
double
Higher Data Type
Lower Data Type
没有
精度丢失
可能有
精度丢失
整形
浮点数

shortint 的类型转化为例说明:

/* 将 short 转为 int */
short s = 0x1234;
int i = s;
// 高 16 位被填充为 0
// i = 0x00001234

/* 将 int 转为 short */
int i = 0x12345678;
short s = i;
// 高 16 位被截断
// s = 0x5678

类型转换

在编程中,类型转换 指的是将一种数据类型转换为另一种数据类型。主要分为两种:

  • 隐式类型转换(Implicit Type Conversion)(也称为 类型提升,Type Promotion)
  • 显式类型转换(Explicit Type Conversion)(也称为 强制转换,Type Casting)
TypeConversioncluster_implicit隐式转换示例cluster_explicit显式转换示例title类型转换 (Type Conversion)implicit隐式类型转换(Implicit Type Conversion)自动进行title->implicitexplicit显式类型转换(Explicit Type Conversion)手动指定title->explicitimplicit_entryimplicit->implicit_entryexplicit_entryexplicit->explicit_entryint_varint i = 5implicit_entry->int_varconversion1i 自动转换为 5.0int_var->conversion1低精度→高精度float_varfloat f = 2.5result1float result = i + f结果: 7.5float_var->result1conversion1->result1float_var2float f = 3.2explicit_entry->float_var2int_var2int i = 5result2int result = (int)f + i结果: 8int_var2->result2conversion2(int)f 强制转换为 3float_var2->conversion2强制转换conversion2->result2warning可能发生精度缺失!conversion2->warning

隐式类型转换

在 C 语言中,当算术运算、赋值和比较表达式中涉及的多个变量类型不同时,如果没有显式指定类型,编译器会自动进行 类型转换

/* 隐式类型转换 */
int i = 5;
float f = 2.5;
float result = i + f;  // i 被隐式转换为 5.0 然后进行计算

你在一个表达式中混合使用 intfloat 时,C 语言会自动进行 类型转换 以使得表达式可以正确计算。通常情况下,低精度类型会被提升到高精度类型,即 int 会被转换为 float

显式类型转换

也可以使用 类型转换运算符 显式地转换一个类型为另一个类型。

/* 显式类型转换 */
int i = 5;
float f = 3.2;
int result = (int)f + i; // f 被显式转换为 3,然后与 i 相加

显式类型转换 会按照你指定的方式进行,在此过程中可能会发生 精度缺失