3月4日 练习讲解

Profile Picture
- Published on Mar 4, 2020🌏 Public

数字

C#中,我把他们大致归类为三种数字类型: 1. 整数 2. 浮点型小数 3. 十进制小数

1.整数

1.1. Int32 / int

Int32是有符号的32位整数。使用32位长度用来记录数值大小。 因为是有符号整数,所以其中1位要用来存放是正数还是负数。

Int32能表示的数值范围为:-2147483648 ~ 2147483647

我们如果执行

 Int32 a =Convert.ToInt32("2147483647")*2;

最终输出的结果为-2

 Int32 a =Convert.ToInt32("2147483647")+1;

最终输出的结果为-2147483648

这种错误出现在运算后,超出了Int32能表示的数值范围的时候。这种错误叫做溢出。

1.2. Int64 / long

Int64是有符号的64位整数,跟Int32以相同的方式存储数值,但是存储数值用的数据长度为Int32的一倍。

表示范围: -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

类型描述范围默认值
SByte/sbyte有符号的8位整数-128~1270
Int16/short有符号16位整数-32,768 ~ 32,7670
Int32/int有符号32位整数-2147483648 ~ 21474836470
Int64/long有符号64位整数-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,8070L
Byte/byte无符号8位整数0~2550
UInt16/ushort无符号16位整数0 ~ 65,5350
UInt32/uint无符号16位整数0 ~ 4,294,967,2950
UInt64/ulong无符号16位整数0 ~ 18,446,744,073,709,551,6150
var str = "100";
Int32 a = Convert.ToInt32(str);
Int64 b = Convert.ToInt64(str);
SByte c = Convert.ToSByte(str);
Int16 d = Convert.ToInt16(str);
Byte e = Convert.ToByte(str);
UInt16 f = Convert.ToUInt16(str);
UInt32 g = Convert.ToUInt32(str);
UInt64 h = Convert.ToUInt64(str);

//当参与运算的数值都是整数是,运算结果会直接舍弃小数点后的数值(不是四舍五入)
var i =-11 / 3;

我们想要从字符串转换的到一个整数,可以使用Convert类下面提供的各种转换方法。

我们的数学运算中,如果出现了参与运算的数值都是整数,那么,最终得到的结果,也会是一个整数,小数部分会被直接去掉(不是四舍五入,是直接去除)

练习1

  1. 要求用户输入两个整数,分别计算他们的加法结果、减法结果和乘法结果,以算式的形式,输出到控制台。
1+2=3
1-2=-1
1×2=2
            Console.WriteLine("请输入第一个数字");
            var inputStr1 = Console.ReadLine();
            Console.WriteLine("请输入第二个数字");
            var inputStr2 = Console.ReadLine();
            var num1 = Convert.ToInt32(inputStr1);
            var num2 = Convert.ToInt32(inputStr2);

            Console.WriteLine( num1 + "+" + num2 + "=" + ( num1 + num2 ) );
            Console.WriteLine(num1 + "-" + num2 + "=" + (num1 - num2));
            Console.WriteLine(num1 + "×" + num2 + "=" + (num1 *  num2));
            Console.WriteLine("请按任意键退出");
            Console.ReadKey();
            Console.WriteLine("请输入第一个数字");
            var inputStr1 = Console.ReadLine();
            Console.WriteLine("请输入第二个数字");
            var inputStr2 = Console.ReadLine();
            var num1 = Convert.ToInt32(inputStr1);
            var num2 = Convert.ToInt32(inputStr2);

            //使用占位符进行输出
            Console.WriteLine("{0}+{1}={2}" , num1,num2,num1+num2);
            Console.WriteLine("{0}-{1}={2}", num1, num2, num1 - num2);
            Console.WriteLine("{0}×{1}={2}", num1, num2, num1 * num2);

            Console.WriteLine("请按任意键退出");
            Console.ReadKey();
  1. 要求用户输入一个大于1的整数,记为n,计算1+2+3+...+n的结果,输出到控制台
            start:
            Console.WriteLine("请输入第一个大于1的整数");
            var inputStr = Console.ReadLine();
            try
            {
                var num = Convert.ToInt32(inputStr);
                if (num > 1)
                {
                    Console.WriteLine("输入正确");
                    //后续代码
                }
                else
                {
                    Console.WriteLine("输入大于1的整数");
                    goto start;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("输入的内容有误,请重新输入");
                goto start;
            }
          
            Console.ReadKey();

上面这种方式,采取标签形式,进行代码运行过程中,跳转到指定位置继续执行。这种方式非常危险,会导致代码的执行逻辑难以控制。不建议大家尝试。

使用递归更加安全:

using System;

namespace Test3
{
    class Program
    {
   
        static void Main(string[] args)
        {
            Start();
            Console.ReadKey();
        }

       static  void Start() {
            Console.WriteLine("请输入第一个大于1的整数");
            var inputStr =Console.ReadLine();;
            try
            {
                var num = Convert.ToInt32(inputStr);
                if (num > 1)
                {
                    Console.WriteLine("输入正确");
                    //后续代码
                }
                else
                {
                    Console.WriteLine("输入大于1的整数");
                    Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("输入的内容有误,请重新输入");
                Start();
            }
        }
    }
}
using System;

namespace Test3
{
    class Program
    {
   
        static void Main(string[] args)
        {
            Start();
            Console.ReadKey();
        }

       static  void Start() {
            Console.WriteLine("请输入第一个大于1的整数");
            var inputStr =Console.ReadLine();
            try
            {
                var num = Convert.ToInt32(inputStr);
                if (num > 1)
                {
                    var str = "";
                    var sum = 0;
                    for (int i = 1; i <= num; i++)
                    {
                        //第一次不拼+号
                        if (str == "")
                        {
                            str += i;
                        }
                        else
                        {
                            str += "+" + i;
                        }
                        sum += i;
                    }
                    Console.WriteLine("{0}={1}",str,sum);
                }
                else
                {
                    Console.WriteLine("输入大于1的整数");
                    Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("输入的内容有误,请重新输入");
                Start();
            }
        }
    }
}

2. 浮点数

1. float 单精度浮点型

符号(1)尾数(23)

可以保证6个有效数字的精度,第7个有效数字开始,就会有精度损失。

1. double 双精度浮点型

符号(1)尾数(52)

可以保证15个有效数字的精度,第16位起开始有精度损失。

3. decimal 十进制整数

这种数据没有精度损失,是一个128 位来表示的十进制数数字。 其中的有效数字为28-29位。

类型描述范围精度默认值
Float/float32位浮点小数-3.4 x 10<sup>38</sup> 到 + 3.4 x 10<sup>38</sup>6到70f
Double/double64位浮点小数(+/-)5.0 x 10<sup>-324</sup> 到 (+/-)1.7 x 10<sup>308</sup>15到16位0d
Decimal/decimal128位表示的十进制数(-7.9 x 10<sup>28</sup> 到 7.9 x 10<sup>28</sup>) / 10<sup>0 到 28</sup>28到29位0m

6位有效数字内的运算可以用float,金额较小的运算用double,金额较大的用decimal。

数据运算

浮点型数据之间的转换

单精度浮点型可以自动转换为双精度浮点型,而双精度浮点型无法自动转换为单精度浮点型。

当单精度浮点型数据和双精度浮点型数据一起参与运算,单精度浮点型会自动转换为双精度浮点型参与运算,得到的结果也是双精度浮点型。

         //float b = d;  //单精度浮点型数据b无法存储双精度浮点型数据
         //float a = f * d; //无法接收,运算得到的是双精度浮点型数据

         double c = f; //将单精度浮点型存到双精度浮点型变量上时,会自动转为双精度浮点型数据。
         double a = f * d;

整数和浮点数

C#当中的运算,参与运算的AB值,如果数据类型不一样,低级的数据将会自动发生升级: 整数 -> 单精度 ->双精度

            float a= 1 / 0.1f;
            double b = 1 / 0.1d;
            double c=  1 / 0.1f / 0.1d;

            int d= 11 / 6;

            double e = 11 / (6 / 0.1d);
            double e2 = 11 / (6d / 0.1d);
            double f = 11 / 60d; //将11升级成double类型,然后跟60d去做触发运算。
            double g = 11d / 60d;
            //  整数 -> float -> double

Decimal和其他数字

            //整数可以自动升级成Decial类型,小数不可以
            var c = 1+ 1m;

            //一定要他去跟浮点小数运算,请自行强转
            var d = (decimal)123456789012345678901234560d + 1m;
            var e =Convert.ToDecimal(123456789012345678901234560d) + 1m;

数字格式化

https://www.cnblogs.com/nele/p/5054029.html

练习

  1. 计算器 ,用户输入两个值,并选择运算方式。输出算式和结果
            Console.WriteLine("请输入数值");
            var num1 = Convert.ToDouble(Console.ReadLine());
            Console.WriteLine("请选择运算方式:\n1. 加法 \n2.减法 \n3.乘法 \n4.除法");
            var key = Console.ReadKey();
            Console.WriteLine("请输入数值");
            var num2 = Convert.ToDouble(Console.ReadLine());
            switch (key.KeyChar)
            {
                case '1':
                    Console.WriteLine("{0}+{1}={2}",num1,num2,num1+num2);
                    break;
                case '2':
                    Console.WriteLine("{0}-{1}={2}", num1, num2, num1 - num2);
                    break;
                case '3':
                    Console.WriteLine("{0}×{1}={2}", num1, num2, num1 * num2);
                    break;
                case '4':
                    Console.WriteLine("{0}÷{1}={2}", num1, num2, num1 / num2);
                    break;
            }
            Console.WriteLine("按任意键退出");
            Console.ReadKey();
  1. 猜数字,随机生成一个100内的数值。然后让用户猜,只给用户返回“太大了”“太小了”的提示,直到用户猜对为止。
   Random r = new Random();
   int value= r.Next(1,101); //返回一个【1-100】中的一个数字
using System;

namespace Test3
{
    
    class Program
    {
        static int a;
        static void Main(string[] args)
        {
            var r = new Random();
            a=r.Next(1, 101); //生成1-100的随机数
            Start();
            Console.ReadKey();
        }
    
        static void Start() {
            Console.WriteLine("请输入一个0~100的数值");
            var num = Convert.ToInt32(Console.ReadLine());
            if (a > num)
            {
                Console.WriteLine("太小了");
                Start();
            }
            else if (a < num)
            {
                Console.WriteLine("太大了");
                Start();
            }
            else {
                Console.WriteLine("答对了!");
            }
        }
    }
}

成功之后,提示用户是否开启新一轮,y/n

将Main函数中的内容提取到一个NewRound方法中,要开启新一轮就去调用NewRound方法。

using System;

namespace Test3
{
    
    class Program
    {
        static int a;
        static void Main(string[] args)
        {
            NewRound();
        }

        /// <summary>
        /// 开启新一轮游戏
        /// </summary>
        private static void NewRound()
        {
            var r = new Random();
            a = r.Next(1, 101); //生成1-100的随机数
            Start();
            Console.ReadKey();
        }


        static void Start() {
            Console.WriteLine("请输入一个0~100的数值");
            var num = Convert.ToInt32(Console.ReadLine());
            if (a > num)
            {
                Console.WriteLine("太小了");
                Start();
            }
            else if (a < num)
            {
                Console.WriteLine("太大了");
                Start();
            }
            else {
                Console.WriteLine("答对了!是否开启新回合? y/n");
                var k=Console.ReadKey();
                if (k.KeyChar == 'y')
                {
                    Console.Clear(); //清理屏幕内容
                    NewRound();
                }
            }
        }
    }
}