相对于整数,浮点数和Decimal类型的数据就没那么复杂了,本课,我们主要了解float、double和decimal数据类型,并讨论整数、浮点数和Decimal混合运算时应该注意的一些情况。

我们知道,计算机处理数据的范围是有限的,整数包含了8位、16位、32位和64位数据类型,而浮点数则包含了单精度和双精度两种,它们对于精度的要求是不同的。float类型对应于System.Single结构类型,用于处理单精度浮点数,保留7位精度;double类型对应于System.Double结构类型,用于处理双精度浮点数,保留15位精度。此外,decimal类型对应于System.Decimal结构类型,用于对精度要求较高的数据处理。下面看一个简单的浮点数和Decimal类型的除法运算示例。

static void Main(string[] args)
{
    Console.WriteLine(5f / 3f);
    Console.WriteLine(5d / 3d);
    Console.WriteLine(5m / 3m);
}

代码执行结果如下图所示。

enter image description here

从运算结果中可以看到float、double和decimal精度上的不同,实际开发时,可以根据计算任务对数据精度的要求选择使用不同的浮点数或decimal类型。

我们已经接触到整数、浮点数和decimal类型,现在的问题是,如果这些类型的数据混合在一起进行算术运算会怎么样呢?这里有一个简单的基本原则,即,当两个不同类型的数据进行运算,会先将取值范围小的数据类型转换为取值范围大的类型,然后进行运算。

下面的代码,我们来观察运算结果的类型。

static void Main(string[] args)
{
    Console.WriteLine((5 / 3).GetType().ToString());
    Console.WriteLine((5 / 3L).GetType().ToString());
    Console.WriteLine((5F / 3).GetType().ToString());
    Console.WriteLine((5L / 3D).GetType().ToString());
    Console.WriteLine((5F / 3D).GetType().ToString());
    Console.WriteLine((5 / 3M).GetType().ToString());
}

代码执行结果如下图所示。

enter image description here

我们可以看到这里给出了六种运算结合,分别是: - int与int类型数据运算,也就是相同类型的数据运算,其结果依然是此类型。 - int与long类型数据运算,结果为long类型(System.Int64)。 - float与int类型数据运算,结果为float类型(System.Single)。 - long与double类型数据运算,结果为double类型(System.Double)。 - float与double类型数据运算,结果为double类型(System.Double)。 - int与decimal类型数据运算,结果为decimal类型(System.Decimal)。

对于常用的数据类型,自动转换的优先级从大到小分别decimal、double、float、long、int、short;请注意,这里主要包含了处理有符号数据的类型。

前面的示例中,数据类型可以自动完成转换,称为“隐式转换”;相对应的,我们还可以对数据进行强制转换;但应注意,在将取值大类型的数据向下转换时,有可能造成数据精度的降低,甚至是得到错误的数据。比如,一个大杯和一个小杯,将小杯的水倒入大杯不会有问题,而将大杯的水倒入小杯,是否能成功,还要看大杯中原来有多少水。

强制转换时,需要在待转换数据使用一对圆括号指定目标类型,如下面的代码。

static void Main(string[] args)
{
    long x = 99L;
    int y = (int)x;
    Console.WriteLine(y.GetType().ToString());
}

毫无疑问,执行结果会显示System.Int32。代码中,首先定义一个long类型的变量x,然后,将其数据转换为int类型并赋值到变量y中,最后显示y的数据类型为System.Int32,即int类型。

接下来,我们做个测试,如下面的代码,我将x的值设置为long.MaxValue。

static void Main(string[] args)
{
    long x = long.MaxValue;
    int y = (int)x;
    Console.WriteLine(y);
}

代码中,我们将x设置为long类型的最大值,然后强制转换为int类型,想一想结果也不可能靠谱。执行结果会显示-1,那么它是怎么来的呢?

我们知道,long类型是64位有符号整数,那么它的最大值的二进制最高位会是0,其他63位是1;而强制转换为int类型后,会进行位截断操作,即将高位的32位舍去,只保留后32位,即32个1组件的二进制数。而int也是有符号类型,所以,当最高位是1时表示这是一个负数,而后面的31个1则是数据绝对值的补码,通过反向计算可以得到30个0和最低位一个1组成的二制数,也就是十进制数1;所以,最终显示的结果是-1。

本课,我们讨论了整数、浮点数、Decimal类型之间可能的转换操作,包括隐式转换和强制转换;另外,还演示了将取值较大整数转换为取值较小整数时会出现什么情况。大家在开发时,要注意数据类型转换时的一些特殊情况,并需要特别小心可能的数据丢失问题,要深入用户数据处理业务,了解数据所需要的精度,合理选择使用数据类型。

这里只是C#中简单的数据转换操作,在整个软件系统中,数据的转换和传递是一个更大的工程,在后续的学习中,我们还会有更多讨论。

CHY软件小屋原创作品!