真会 C# 吗 03

声明

本文内容来自微软 MVP solenovex 的视频教程——真会C#吗?-- C#全面教程,大致和第 6 课—— 基础 - 数值类型(入门+) 对应。

本文主要包括以下内容:

  1. 数值类型

数值类型

数值类型包括,整型和浮点型。如下图所示:

真会 C# 吗 03_第1张图片
Numeric Types.jpg

整数 Literal

整数类型的 Literal 可使用 10/16/2 进制符号,16 进制是在前面加上 0x 前缀,进制是在前面加上 0b 前缀,C# 7.0 开始可以在数值中使用下划线提高可读性。

int x = 127;
long y = 0x7F;
int million = 1_000_000;
var b = 0b1010_1011_1100_1101_1110_1111;

实数 Literal

可使用小数点,指数形式。

double d = 1.5;
double million = 1E06;

数值 Literal 的类型推断

默认情况下,编译器会推断一个数值 Literal 是 Double 还是整数类型,如果包含小数点,或以指数形式展现,那么就是 Double 类型
否则 Literal 的数值是 int,uint,long,ulong 里第一个能容纳该数值的类型。

Console.WriteLine ( 1.0.GetType()); // Double (double)
Console.WriteLine ( 1E06.GetType()); // Double (double)
Console.WriteLine ( 1.GetType()); // Int32 (int)
Console.WriteLine ( 0xF0000000.GetType()); // UInt32 (uint)
Console.WriteLine (0x100000000.GetType()); // Int64 (long)

数值的后缀

数值的后缀会显式定义 Literal 的类型,U、L 很少使用,因为 Uint,Long,Ulong 要么可以被推断出来,要么可以从 Int 隐式转换过来,F、M 是比较有用的,当指定 Float 或 Decimal 的 Literal 的时候,应该加上。

long i = 5; // Implicit lossless conversion from int literal to long
double x = 4.0;
float f = 4.5F;
decimal d = -1.23M; // Will not compile without the M suffix.
真会 C# 吗 03_第2张图片
Numeric suffixes.jpg

类型转换

整数类型

当目标类型可以容纳源类型时,整数转换是隐式的,否则就要显式转换。

int x = 12345; // int is a 32-bit integer
long y = x; // Implicit conversion to 64-bit integral type
short z = (short)x; // Explicit conversion to 16-bit integral type

浮点型

Float 可以隐式的转换为 Double,Double 必须显式的才能转换为 Float。

浮点型和整数类型转换

所有的整数类型都可以隐式的转换为所有的浮点类型,反过来必须进行显式转换。

int i = 1;
float f = i;
int i2 = (int)f;

Note:当前浮点型转为整型时,小数部分将会被截断。
把一个很大的整数隐式转换为浮点类型后,会保证量级不变,但是偶尔会丢失精度。因为浮点类型有更多的量级,而精度可能不足。

int i1 = 100000001;
float f = i1; // Magnitude preserved, precision lost
int i2 = (int)f; // 100000000

Decimal 转换

所有的整数类型可以被隐式的转换为 Decimal 类型,反过来则必须进行显式转换。

算术操作符

以下运算符对数值类型执行算术运算:

  • 一元 ++(增量)、--(减量)、+(加) 和 -(减)运算符。

  • 二元 *(乘)/(除)%(余数)+(加) 和 -(减) 运算符。

这些运算符支持所有整型和浮动数值类型。

++(增量)、--(减量)

增量运算符以两种形式进行支持:后缀增量运算符 x++ 和前缀增量运算符 ++x。

int x = 0, y = 0;
Console.WriteLine (x++); // Outputs 0; x is now 1
Console.WriteLine (++y); // Outputs 1; y is now 1

除法

整型会截断余数,除数变量为 0,会抛出 DivideByZeroException 运行时异常,除数 Literal 为 0 则编译错误。

int a = 2 / 3; // 0
int b = 0;
int c = 5 / b; // throws DivideByZeroException

Overflow 溢出

在运行时,整型的算术操作可能会引起溢出,默认情况下,不会抛出异常,结果类似于“环绕”行为。

默认开启算术的 Overflow 检查,可使用 unchenked 部分关闭检查。

int a = int.MinValue;
a--;
Console.WriteLine (a == int.MaxValue); // True
Overflow Checked 操作符
  • Checked 会告诉运行时,如果整型的表达式或语句超出了该类型的极限,就会抛出 OverflowException。

  • Checked 操作符对 ++,--,+,-,*,/ 起作用。

  • Checked 可以用于表达式或语句。

  • Checked 对 Float,Double 不起作用,因为它们有无限的值。

  • 常量表达式的 Overflow 检查,编译时算出来的表达式总会时行溢出检查,除非使用 unchenced 操作符。

int a = 1000000;
int b = 1000000;
int c = checked (a * b); // Checks just the expression.
checked // Checks all expressions
{ // in statement block.

c = a * b;

}

int x = int.MaxValue;
int y = unchecked (x + 1);
unchecked { int z = x + 1; }

// int x = int.MaxValue + 1; // Compile-time error
// int y = unchecked (int.MaxValue + 1); // No errors

按位操作符

C# 提供如下图所示按位操作符:

真会 C# 吗 03_第3张图片
Bitwise operators.jpg

8/16 位整数类型

byte,sbyte,short,ushort,没有自己的操作符,C# 会按需对它们进行隐式转换到大一点的整数类型。

short x = 1, y = 1;
short z = x + y; // Compile-time error

short z = (short) (x + y); // OK

Float,Double 的特殊值

浮点表达式可以包含下列值集:
NaN,正无穷,负无穷,-0,MaxValue,MinValue,Epsilon。

Float/Double 除以 0

Console.WriteLine ( 1.0 / 0.0); // Infinity
Console.WriteLine (−1.0 / 0.0); // -Infinity
Console.WriteLine ( 1.0 / −0.0); // -Infinity
Console.WriteLine (−1.0 / −0.0); // Infinity

NaN

使用 == 操作符时,NaN 不等于任何一个值,包括 NaN 使用 object.Equals() 方法时,两个NaN是相等的,验证某个值是否为 NaN,float.IsNan(),double.IsNan()。

Console.WriteLine ( 0.0 / 0.0); // NaN
Console.WriteLine ((1.0 / 0.0) − (1.0 / 0.0)); // NaN

Console.WriteLine (0.0 / 0.0 == double.NaN); // False

Console.WriteLine (double.IsNaN (0.0 / 0.0)); // True

Console.WriteLine (object.Equals (0.0 / 0.0, double.NaN)); // True
真会 C# 吗 03_第4张图片
Special Float and Double Values.jpg

Double vs. Decimal

Double 基于 2 计算,Decimal 基于 10 计算。Double 比 Decimal 的计算速度更快,大约 10 倍左右。Double 适用于科学计算,例如坐标值;Decimal 适用于财务计算,或者人造数据。

实数的舍入错误

  • Float 和 Double 是基于 2 来表示数值的,只有可用 2 表达的数值才是准确的,大多数带有小数部分的Literal都不会被精确的表达出来。

  • Decimal 是基于 10,可以精确的表达基于 10 的数据,包括基于 2,5 的数据。

  • 循环数据,Double 和 Decimal 都不可以精确的表达循环数据。

float tenth = 0.1f; // Not quite 0.1
float one = 1f;
Console.WriteLine (one - tenth * 10f); // -1.490116E-08

decimal m = 1M / 6M; // 0.1666666666666666666666666667M
double d = 1.0 / 6.0; // 0.16666666666666666

decimal notQuiteWholeM = m+m+m+m+m+m; // 1.0000000000000000000000000002M
double notQuiteWholeD = d+d+d+d+d+d; // 0.99999999999999989

Console.WriteLine (notQuiteWholeM == 1M); // False
Console.WriteLine (notQuiteWholeD < 1.0); // True
真会 C# 吗 03_第5张图片
double Versus decimal.jpg

参考

Integral types table (C# Reference)

Floating-point types table (C# Reference)

Value types (C# Reference)

Double Struct

Arithmetic operators (C# Reference)

Bitwise and shift operators (C# Reference)

你可能感兴趣的:(真会 C# 吗 03)