【NOI】C++程序设计入门四


前言

欢迎步入C++程序设计的奇妙世界,本章节我们将聚焦于编程领域中一个至关重要且广泛使用的数据类型——浮点数。浮点数,作为数学和现实世界计量不可或缺的一部分,在计算机科学中扮演着举足轻重的角色。无论是精确的科学计算,还是日常的金融交易记录,正确理解和运用浮点数都是编程技能中的一项基本功。本章节将引领你深入了解C++中的浮点型数据——float与double,揭示它们的存储细节、精度差异以及如何在实际编程中灵活应用它们进行精确或高效的数值处理。让我们一同揭开浮点数的神秘面纱,为你的编程之旅增添一份坚实的基石。

学习路线:C++从入门到NOI学习路线

学习大纲:C++全国青少年信息学奥林匹克竞赛(NOI)入门级-大纲


一、浮点型(float和double)

在C++中,浮点型(floating-point types)是用来存储带有小数部分的数值的数据类型。

C++标准定义了三种基本的浮点类型:float、double 和 long double。它们的主要区别在于存储大小和精度。float通常使用32位来存储,而double则使用64位。

你可以把float想象成一个普通的杯子,而double则是一个大杯子。当你需要装一点果汁时,普通的杯子就足够了。但是,如果你需要装很多果汁,或者你需要确保果汁的每一滴都精确无误,那么你就需要一个大杯子,也就是double。

在这里插入图片描述

1.float类型

  1. 它用于表示单精度浮点数。
  2. 占用4个字节(32位),其中1位用于符号,8位用于指数,23位用于尾数(有效数字)。
  3. 根据IEEE 754标准,可以表示大约7位十进制数字的精度。

float 示例

#include <iostream>
using namespace std;

int main() {
   
   
    // 声明并初始化float类型的变量
    float pi_float = 3.14159f; // 注意末尾的 'f' 或 'F' 表示这是一个float类型的字面值

    // 输出float类型的变量
    cout << "The value of pi as a float: " << pi_float << endl;

    return 0;
}

在这个例子中,我们声明了一个名为pi_float的float类型变量,并将其初始化为3.14159。由于直接写的3.14159默认会被认为是double类型的字面值,所以在赋值给float变量时,我们需要在数值后面加上f或F来明确指出这是一个float类型的数值。

2.double类型

  1. 它用于表示双精度浮点数,提供了比float更高的精度。
  2. 占用8个字节(64位),其中1位用于符号,11位用于指数,52位用于尾数。
  3. 可以提供大约15位十进制数字的精度。

double 示例

#include <iostream>
using namespace std;

int main() {
   
   
    // 声明并初始化double类型的变量
    double pi_double = 3.141592653589793; // 对于double,不需要像float那样在数值后加标识符

    // 输出double类型的变量
    cout << "The value of pi as a double: " << pi_double << endl;

    return 0;
}

在这个例子中,我们声明了一个名为pi_double的double类型变量,并直接将其初始化为3.141592653589793。因为double是处理浮点数时的默认类型,所以可以直接赋值而不需添加任何后缀。

这涉及到更高位的运算时,我们会学习使用高精度算法,因此long double类型就不做介绍,double完全够我们使用。

二、保留小数的方法

方法一:

  1. 引入头文件 #include < iomanip>
  2. 输出格式:cout<<fixed<<setprecision(保留几位填数字几)<<输出<<endl;

示例

#include <iostream>
#include <iomanip> // 引入iomanip头文件以使用fixed和setprecision

using namespace std;

int main() {
   
   
    double number = 3.14159;
    
    // 使用fixed确保小数点后固定位数,setprecision设置保留的小数位数
    cout << fixed << setprecision(2) << number << endl;
    
    return 0;
}

在这个例子中,number的值为3.14159,通过fixed和setprecision(2),输出结果会是3.14,即保留了两位小数。

几点注意:

  1. fixed确保小数点后有固定数量的数字,即使它们是0。
  2. setprecision(n)设置输出浮点数的精度为n位小数,但如果不与fixed一起使用,它可能不会以预期的方式工作,尤其是在数值较小或较大的情况下。
  3. 这些操作只影响输出的显示方式,并不影响变量本身的值。

方法二:

printf(“%.1f”,)是C语言中的格式化输出函数,用于将浮点数按照指定格式输出。其中%.1f表示输出浮点数,保留小数点后1位。在括号中填入需要输出的浮点数即可。

  1. 输出格式:printf(“%.1f”,输出);

示例

#include <cstdio> // 在C++中,为了使用printf,需要包含<stdio.h>或<stdio>

int main() {
   
   
    double number = 3.14159;
    
    // 使用printf函数输出,%.1f指保留1位小数
    printf("%.1f\n", number); // 注意\n用于换行
    
    return 0;
}

在这个例子中,%.1f是一个格式说明符,其中%是所有格式说明符的开始标志,.1表示保留一位小数,f指示要输出的是浮点数。printf函数会将number的值按照这个格式输出。

三、类型转换

类型转换指的是将变量的数据类型进行变换。

在这里插入图片描述

这里可能会有疑问,毕竟我们在前面讲过,数据类型的作用就是限定变量的存储形式和数值范围。这样数据类型可以确保了程序的正确性和效率。

实际上这里我们要讲的类型转换和前面的内容并不冲突,因为实现类型转换是有前提的—安全有效

首先是安全性:

安全性是指类型转换不会引入潜在的错误或异常情况。一个安全的类型转换应该满足以下条件:

  • 无数据丢失:转换过程中不应该丢失重要的信息。例如,将double转换为int时会截断小数部分,这可能导致数据丢失。

在这里插入图片描述

  • 不违反访问权限:转换不应绕过语言的访问控制机制。例如,使用const_cast移除const属性后修改常量值是不安全的行为。
  • 不产生未定义行为:转换不应导致程序进入一种不确定的状态。例如,将一个指向派生类的指针强制转换为基类指针是安全的,但反之则可能不安全(除非使用dynamic_cast)。
  • 多态性正确处理:对于涉及多态的转换,如从基类指针到派生类指针的转换,应该使用dynamic_cast来确保运行时检查和安全。
  • 内存布局兼容:对于指针类型的转换,特别是使用reinterpret_cast时,源类型和目标类型的内存布局必须兼容,否则可能会导致严重的错误。

其次是有效性:

有效性是指类型转换能够成功完成,并且结果是有意义的。有效的类型转换应该满足以下条件:

  • 转换前后语义一致:转换后的值应该保持与转换前的值相同的逻辑意义。例如,将温度从摄氏度转换为华氏度
    一个有效的转换,因为两种表示方法都是描述同一个物理量。
  • 符合预期用途:转换的结果应该适用于预期的操作。例如,如果需要进行浮点运算,将整数转换为浮点数是有效的。
  • 遵循语言规则:转换应该遵守C++语言的规则和标准。例如,static_cast可以用于基本类型的转换,但不能用于不相关的类之间的转换。
  • 编译器支持:转换应该得到编译器的支持,并且能够在所有支持的平台上一致地工作。

说那么多其实就是告诉大家,该转才转,别没事找事。

3.1 隐式转换

隐式转换通常由编译器自动执行,前提是源类型和目标类型之间存在标准转换序列。这些转换通常是安全的,并且不会导致数据丢失或不确定的行为。

在算术表达式中,如果操作数的类型不同,编译器会尝试将它们转换为相同的类型以进行计算。

int a = 5;
cout<<a+0.5;  // 隐式转换:int到double

又或者当一个表达式需要某种类型的值而实际提供的却是另一种类型时,如果这两种类型之间可以安全地相互转换,编译器就会执行这种转换。例如,将整数赋给浮点型变量:

int a = 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明月别枝惊鹊丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值