C# 中的基本数值类型
在之前的文章中(地址:https://www.vinanysoft.com/c-sharp-basics/introducing/),以 HelloWorld 程序为基础,介绍 C# 语言、它的结构、基本语法以及如何编写最简单的程序有了初步理解。
接下来介绍基本的 C# 类型,继续巩固 C# 的基础知识。本系列文章到目前为止只用过少量的内置数据类型,而且只是一笔带过。在 C# 中有大量的类型,而且可以通过合并类型来创建新类型。
但 C# 有几种类型非常简单,是其他所有类型的基础,它们称为预定义类型(predefined type)或基元类型( primitive type)。
C# 提供了 16 种预定义类型,如下图所示。其中包括 13 种简单类型和 3 种非简单类型。
所有预定义类型的名称都由全小写的字母组成。预定义的简单类型包括以下 3 种。
- 11 种数值类型。
- 不同长度的有符号和无符号整数类型。
- 用于科学计算的二进制浮点类型
float
和double
。 - 一种用于金融计算的十进制高精度浮点类型
decimal
。与float
和double
不同,decimal
类型可以准确地表示分数。decimal
类型常用于货币的计算。
- 一种
Unicode
字符类型char
。 - 一种布尔类型
bool
。bool
类型表示布尔值并且必须为true
或false
。
非简单类型如下:
object
,它是所有其他类型的基类。string
,它是一个Unicode
字符数组。dynamic
,使用动态语言编写的程序集时使用。
所有预定义类型都直接映射到底层的 .NET 类型。C# 的类型名称就是 .NET 类型的别名,所以使用 .NET 的类型名称也能很好地符合 C# 语法,不过并不鼓励这样做。在 C# 程序中,应该尽量使用 C# 类型名称而不是 .NET类型名称。
整数类型
C# 有八种整数类型,可选择最恰当的一种来存储数据以避免浪费资源。下表列出了 C# 支持的整型类型:
C# 类型/关键字 | 范围 | 大小 | .NET 类型 |
---|---|---|---|
sbyte | -128 到 127 | 8 位带符号整数 | System.SByte |
byte | 0 到 255 | 无符号的 8 位整数 | System.Byte |
short | -32,768 到 32,767 | 有符号 16 位整数 | System.Int16 |
ushort | 0 到 65,535 | 无符号 16 位整数 | System.UInt16 |
int | -2,147,483,648 到 2,147,483,647 | 带符号的 32 位整数 | System.Int32 |
uint | 0 到 4,294,967,295 | 无符号的 32 位整数 | System.UInt32 |
long | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 64 位带符号整数 | System.Int64 |
ulong | 0 到 18,446,744,073,709,551,615 | 无符号 64 位整数 | System.UInt64 |
C# 所有基元类型都有短名称(最左列)和完整名称(最右列)。完整名称对应 BCL(基类库)中的类型名称。
由于基元数据类型是其他类型的基础,所以 C# 为基元数据类型的完整名称提供了短名称(或称为缩写)。其实从编译器的角度看,两种名称完全一样,最终都生成相同的代码。事实上,检查最终生成的 CIL 代码,根本看不出源代码具体使用的名称。
例如,以下声明声明了相同类型的变量:
int a = 123;
System.Int32 b = 123;
C# 支持完整 BCL 名称和关键字,造成开发人员犯难在什么时候用什么。不要时而用这个,时而用那个,最好坚持用一种。
C# 开发人员一般用 C# 关键字。例如,用 int
而不是 System.Int32
,用 string
而不是 System.String
(甚至不要用 String
这种简化形式)。
浮点类型(float
和 double
)
C# 支持以下预定义浮点类型:
C# 类型/关键字 | 大致范围 | 精度 | 大小 | .NET 类型 |
---|---|---|---|---|
float | ±1.5 x 10−45 至 ±3.4 x 1038 | 大约 6-9 位数字 | 4 个字节 | System.Single |
double | ±5.0 × 10−324 到 ±1.7 × 10308 | 大约 15-17 位数字 | 8 个字节 | System.Double |
在上表中,最左侧列中的每个 C# 类型关键字都是相应 .NET 类型的别名。 它们是可互换的。 例如,以下声明声明了相同类型的变量:
double a = 12.3;
System.Double b = 12.3;
decimal
类型
C# 类型/关键字 | 大致范围 | 精度 | 大小 | .NET 类型 |
---|---|---|---|---|
decimal | ±1.0 x 10-28 至 ±7.9228 x 1028 | 28-29 位 | 16 个字节 | System.Decimal |
与 float
和 double
相比,decimal
类型具有更高的精度和更小的范围,因此它适合于财务和货币计算。
浮点数舍入误差
float
和 double
在内部都是基于 2 来表示数值的。因此只有基于 2 表示的数值才能够精确表示。事实上,这意味着大多数有小数部分的字面量(它们都基于 10)将无法精确表示。例如:
float f1 = 1F;
float f2 = 0.9F;
Console.WriteLine(f1 - f2);
double d1 = 1D;
double d2 = 0.9D;
Console.WriteLine(d1 - d2);
decimal decimal1 = 1M;
decimal decimal2 = 0.9M;
Console.WriteLine(decimal1 - decimal2);
输出
0.100000024
0.09999999999999998
0.1
这就是为什么 float
和 double
不适合金融计算。相反,decimal
基于 10,它能够精确表示基于 10 的数值(也包括它的因数,基于 2 和基于 5 的数值)。因为实数的字面量都是基于 10 的,所以 decimal
能够精确表示像 0.1
这样的数。然而,float
、double
和 decimal
都不能精确表示那些基于 10 的循环小数:
decimal m = 1M / 6M;
Console.WriteLine(m);
decimal m2 = m + m + m + m + m + m;
Console.WriteLine(m2);
Console.WriteLine();
double d = 1d / 6d;
Console.WriteLine(d);
double d2 = d + d + d + d + d + d;
Console.WriteLine(d2);
输出
0.1666666666666666666666666667
1.0000000000000000000000000002
0.16666666666666666
0.9999999999999999
字面量
字面量(literal value)表示源代码中的固定值。
Console.WriteLine(123);
Console.WriteLine(456.789);
默认情况下,输入带小数点的字面量,编译器自动把它解释成 double
类型。 如果输入的是整数值(没有小数点)通常默认为 int
, 如果值太大,以至于无法用 int
来存储。编译器会把它解释成 long
。
static void Main(string[] args)
{
var expectIsInt = 123;
var expectIsLong = 9223372036854775807;
var expectIsDouble = 3.14;
Console.WriteLine($"expectIsInt 的类型是:{expectIsInt.GetType().Name};" +
$"expectIsLong 的类型是:{expectIsLong.GetType().Name};" +
$"expectIsDouble 的类型是:{expectIsDouble.GetType().Name}");
}
输出
expectIsInt 的类型是:Int32;expectIsLong 的类型是:Int64;expectIsDouble 的类型是:Double
由于带小数点的值默认为 double
类型,所以下面输出的结果中,超过可容纳的精度部分会被丢弃。
static void Main(string[] args)
{
Console.WriteLine(5.141231231234567898765);
}
输出
5.141231231234568
要显示具有完整精度的数字,必须将字面量显式声明为 decimal
类型,通过追加一个 M
(或者 m
)来实现。
static void Main(string[] args)
{
Console.WriteLine(5.141231231234567898765M);
}
输出
5.141231231234567898765
还可以使用 F
和 D
作为后缀,将字面量分别显式声明为 float
或者 double
。 对于整数数据类型,整数字面量的类型是像下面这样确定的:
如果整数字面量没有后缀,则其类型为以下类型中可表示其值的第一个类型:
int
、uint
、long
、ulong
。如果整数字面量以
U
或u
为后缀,则其类型为以下类型中可表示其值的第一个类型:uint
、ulong
。如果整数字面量以
L
或l
为后缀,则其类型为以下类型中可表示其值的第一个类型:long
、ulong
。备注:可以使用小写字母
l
作为后缀。 但是,这会生成一个编译器警告,因为字母l
可能与数字1
混淆。 为清楚起见,请使用L
。如果整数字面量的后缀为
UL
、Ul
、uL
、ul
、LU
、Lu
、lU
或lu
,则其类型为ulong
。
字面量的后缀不区分大小写。但一般推荐大写,避免出现小写字母 l
和数字 1
不好区分的情况。
从 C# 7.0 开始提供支持将 _
用作数字分隔符,可以将数字分隔符用于所有类型的数字文本。
double d = 3D;
d = 4d;
d = 3.934_001;
float f = 3_000.5F;
f = 5.4f;
decimal myMoney = 3_000.5m;
myMoney = 400.75M;
C# 支持使用科学记数法,指数记数法要求使用 e
或 E
中缀,在中缀字母后面添加正整数或者负整数,并在字面量最后添加恰当的数据类型后缀。
double d = 0.42e2;
Console.WriteLine(d); // output 42;
float f = 134.45E-2f;
Console.WriteLine(f); // output: 1.3445
decimal m = 1.5E6m;
Console.WriteLine(m); // output: 1500000
使用 0x
或 0X
前缀表示十六进制计数法,在 C# 7.0 和更高版本中使用 0b
或 0B
前缀表示二进制计数法。
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;
总结
C# 语言的基元类型包括八种整数类型、两种用于科学计算的二进制浮点类型、一种用于金融计算的十进制浮点类型。浮点型存在舍入误差,使用的时候要注意。
C# 中的基本数值类型的更多相关文章
- C++11中string与数值类型的转换
C++中string与数值类型的相互转换记录 string转int.double.long string s = "123.456"; // string -> int co ...
- 在javaScript中把非数值类型的数据自动转换为数值类型的两种方式
一.使用Number()函数. 二.使用parseInt()/parseFloat()函数. 详情: 一.使用Number()函数将非数值类型的数据自动的转化为数组类型 Number()函数可以将任何 ...
- Java中初级数值类型的大小, volatile和包装类wrapped type的比较
Java中的初级数值类型 Java是静态类型语言, 所有的变量必须先声明再使用. 其初级类型一共8种: boolean: 数据只包含1bit信息, 但是占空间为8-bit, 默认值为false byt ...
- 当向计算机中存入一个float类型的数值2.2 后,在从计算机中读出输出,这时2.2 的值已经发生了变化(转)
problom : 'f1' value hava been changed when output. reason : the binary repersentation of 2.2f is : ...
- MSSQL中 数值类型转换为千分号的解决方案
转自:http://www.maomao365.com/?p=4797 前言:最近需要将报表中关于数值部分的数据,采用千分号的形式展现给用户,下面将讲解如何制作1 将数值类型转换为 money类型2 ...
- MySQL中int(M)和tinyint(M)数值类型中M值的意义
在一开始接触MySQL数据库时,对于int(M)及tinyint(M)两者数值类型后面的M值理解是最多能够插入数据库中的值不能大于M: 后来工作后,也是一边学习一边使用,之后的理解是其中的M的意思是插 ...
- C#中货币类型和数值类型、字符串类型的转化
1.定义textbox的数据 private void Form1_Load(object sender, EventArgs e) { this.textBox1.Text = String.For ...
- Python中的数值类型总结
本文参考书:<Learning Python>中文版--<Python 学习手册>第四版 Python中包含大量的数值类型,他们中的大部分与其他编程语言保持一致,因此学习他们就 ...
- oracle中的常用函数、字符串函数、数值类型函数、日期函数,聚合函数。
一.字符串的常用函数. --一.oracle 字符串常用函数 --1. concat 连接字符串的函数,只能连接[两个]字符串. 字符写在括号中,并用逗号隔开! --2."||"符 ...
随机推荐
- nginx代理跨域,根据路径参数改变目标服务器地址
我们都知道nginx是可以做跨域代理的: location ^~ /visited-path/ { proxy_pass http://another-domain/; } 举个例子:假如我们的代理服 ...
- VMware密钥
UG5J2-0ME12-M89WY-NPWXX-WQH88 GA590-86Y05-4806Y-X4PEE-ZV8E0 YA18K-0WY8P-H85DY-L4NZG-X7RAD UA5DR-2ZD4 ...
- Linux入侵痕迹检测方案【华为云技术分享】
背景说明 扫描是一切入侵的基础,通过扫描来发现目标主机是否为活动主机.操作系统是什么版本.开放了哪些服务等.扫描技术纷繁复杂,新的扫描技术也层出不穷,不可能穷举所有扫描技术,下面按入侵步骤对主机扫描. ...
- 利用 Flask 动态展示 Pyecharts 图表数据的几种方法
本文将介绍如何在 web 框架 Flask 中使用可视化工具 pyecharts, 看完本教程你将掌握几种动态展示可视化数据的方法,不会的话你来找我呀- Flask 模板渲染 1. 新建一个项目fla ...
- ASP.NET Core 选项模式源码学习Options Configure(一)
前言 ASP.NET Core 后我们的配置变得更加轻量级了,在ASP.NET Core中,配置模型得到了显著的扩展和增强,应用程序配置可以存储在多环境变量配置中,appsettings.json用户 ...
- Spring bean 初始化失败
在一个*context.xml 配置文件 A 中, 有个定义的bean B, 把 A 添加到 application-context.xml 中,发现B不能正常初始化. 解决办法: 添加 <co ...
- 记一次Elasticsearch OOM的优化过程——基于segments force merge 和 store type 转为 niofs
首选,说明笔者的机器环境(不结合环境谈解决方案都是耍流氓): cpu 32核,内存128G,非固态硬盘: RAID0 (4T * 6),单节点,数据量在700G到1800G,索引15亿~21亿.敖丙大 ...
- Springboot结合Redis
安装 Redis 安装 gcc Yum install gcc-c++ 解压 redis.3.0.0.tar.gz 压缩包 tar -zxvf redis-3.0.0.tar.gz 进入解压后的目 ...
- jQuery中的层级选择器
话不多说,请看效果: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...
- Codevs-4919 线段树练习4(区间加上一个值并求摸个区间整除k的数的个数,线段树+数组维护)
给你N个数,有两种操作 1:给区间[a,b]内的所有数都增加X 2:询问区间[a,b]能被7整除的个数 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数,再接下来一 ...