(转发)详解汽车UDS诊断协议(一)

article/2025/10/28 22:54:28

一.概述

UDS(UnifiedDiagnostic Services,统一诊断服务,有时也称增强诊断)是ISO-14229定义的基于OSI模型中应用层的协议。其中,ISO 14229-1定义了诊断服务,但不涉及网络层及实现手段,只有应用层的内容,因此可在不同的汽车总线(如CAN, LIN, Flexray, Ethernet和K-line等)上实现。

结合ISO 15765-3和ISO 14229-1则实现了基于CAN总线的UDS汽车统一诊断服务。如下图所示:

ISO15765-4规定排放相关的诊断内容

OSI各层汽车制造商的增强诊断法规要求的排放相关诊断(OBD)
诊断应用用户定义ISO 15031-5
应用层ISO 15765-3/ISO 14229-1ISO 15031-5
表示层
会话层ISO 15765-3ISO 15765-4
传输层
网络层ISO 15765-2ISO 15765-4
数据链路层ISO 11898-1ISO 15765-4
物理层用户定义ISO 15765-4

UDS不是法规要求的,没有统一实现标准,其优势在于方便生产线检测设备的开发,同时更大的方便了售后维修保养和车联网的功能实现。

诊断通信的过程从用户角度来看非常容易理解,诊断仪发送诊断请求(request),ECU给出诊断响应(response),而UDS就是为不同的诊断功能的request和response定义了统一的内容和格式。

二.诊断服务交互方式

UDS本质上是一种定向的通信,是一种交互协议(Request/Response),即诊断方给ECU发送指定的请求数据(Request),ECU反馈给诊断方信息(Response)。

Diagnostic Request的格式:

DiagnosticRequest的格式可以分为两类:

一类是拥有sub-function的;

一类是没有sub-function的;

Service ID(以下简称SID)的长度固定为1个字节,代表了这条诊断命令执行的什么功能。Sub-function的长度也是1个字节,它通常表示对这个诊断服务的具体操作,比如是启动、停止还是查询这个诊断服务。而后面的Parameter则根据各个诊断服务的不同具有不同的内容,长度和格式并没有统一规格,它用于限定诊断服务执行的条件,比如某个诊断服务执行的时间等。Parameter的一个重要应用是作为标识符,标识诊断请求要读出的数据内容。

有一点要补充的是,其实Sub-function严格来说是7个bit,而不是1个byte,因为它的最高位bit被用于抑制正响应(Suppress Ppositive Response, SPR),如果这个bit被置1,则ECU不会给出正响应(PositiveResponse);如果这个bit被置0,则ECU会给出正响应。这样做的目的是可以告诉ECU不要发不必要的Response,从而节约通信资源。

Diagnostic Response的格式:

Diagnosticresponse分为positive和negative两类。

positive response意味着诊断仪发过来的诊断请求被执行了,而negativeresponse则意味着ECU因为某种原因无法执行诊断仪发过来的诊断请求,而无法执行的原因则存在于negative response报文中的NRC中

Positive response肯定响应的格式是由三部分组成,其中的response SID这个字节作为诊断请求的echo,回复[SID+0x40],例如请求10,响应50;请求22,响应62,回复的是一组数据。后面的两个字节分别为子功能及其他,视具体的诊断服务而定。

Negative response否定响应的格式固定为3个字节,回复[7F+SID+NRC],第一个字节为0x7F,第二个字节是被拒绝掉的SID,第三个字节是NRC否定响应码。比如,若ECU给出7F22 13这个negative response,则说明SID=22这个服务因为诊断请求数据长度不对(NRC=13)的原因而无法执行。NRC否定响应码如下图所示:

举例来说:

以CAN总线网络举例。八个帧数据字节,第一字节被网络层占用(ISO 15765-2)。

诊断端发送请求(Request):02 10 02 xx xx xx xx xx ; 02是网络层单帧SF,代表数据域有2个字节,10是SID,02是子功能。

若ECU的肯定响应(Positive Response):02 50 02 xx xx xxxx xx;02同上,10+40表示对SID的肯定回复,02是子功能(在下文进行详解)。

若ECU的否定响应(Negative Response):03 7F 10 22 xx xxxx xx;03同上,代表数据域有3个字节,7F表示否定响应,10是SID,22是NRC。

通俗来说,诊断通信的过程就是诊断仪和ECU交换数据,前者发的是request,后者发的是response,而UDS最重要的作用就是定义了这些request和response的格式和内容。

三.诊断服务内容

UDS协议共定义以下26种服务:

本文首先将针对上图中关于“诊断和通信管理类”“数据传输类”“存储数据传输”的服务进行解读。后续将在下文进行更新

诊断和通信管理类服务

1. DiagnosticSessionControl(0x10)

$10用于控制ECU在不同的session之间进行转换,session可以看作是ECU所处的一种软件状态,在不同的session中诊断服务执行的权限不同。其Request请求格式如下所示:

DiagnosticSessionControl诊断request的格式

第一个字节即SID,这里为0x10。第二个自己即$10服务的子功能,功能列表如下所示:

ECU上电时,进入的是默认会话0x01(Default)。如果您进入了一个非默认会话的状态,一个定时器会运转,如果一段时间内没有请求,那么到时间后,诊断退回到默认会话01。当然,我们有一个$3E的服务,可以使诊断保持在非默认的状态。

ECU上电之后,由于默认处在0x01 defaultSession中,而在这个session中很多诊断服务不可以执行,导致很多诊断相关的数据不能读取或写入。

一般的诊断仪启动之后,会给ECU发送10 03,即让ECU进入 extendedDiagnosticSession中,在这个session中可执行的诊断服务就很多了。

而如果要让ECU保持在non-defaultSession中,则需要诊断仪每隔固定的时间发送0x3E服务,ECU才会知道诊断仪有和自己通信的需求,从而保持在non-defaultSession中。

另一个常用的session是0x02 ProgrammingSession,在这个session中可以进行软件刷写的一系列诊断服务。

0x40 – 0x5F 这个范围中的session由整车厂自定义使用,比如,某些诊断服务或诊断数据的操作需要在生产线上执行,即所谓的End-Of-Line,整车厂可以从这个范围中选择一个值来表示EOL session;又或者在开发阶段需要某种“超级”session,则也可以从这里选一个值用来使ECU进入开发模式的session。

DiagnosticSessionControl这个服务非常简单,但是它却是ECU和诊断通信的第一条诊断命令。

ECUReset (0x11)

ECUReset 这条指令的用途是通过诊断请求使ECU重启。

ECUReset 诊断request的格式

第一个字节是SID,即0x11。第二个字节的低7bit是sub-function,用于指示ECU将模拟哪种方式进行重启。 常用的sub-function包括(只举2个例子,UDS还定义了很多其他的值)

0x01 hardReset 模拟KL30的重启

0x02 keyOffOnReset 模拟KL15的重启

当我们通过诊断命令改写了ECU的某些数据,或者对ECU进行了某些设置,只有将ECU重启才能将这些配置生效,所以就有了这个诊断命令。在ECUReset 执行之后,ECU会从Non-defaultsession回退到defaultsession中。

SecurityAccess(0x27)

厂家可能会为ECU定义某些安全级别稍微高一些的诊断服务,在执行此类服务之前,就需要执行SecurityAccess 这个诊断命令,进行一个简单的身份验证。

完成SecurityAccess 有以下步骤:

根据UDS对$27服务的定义:

0x03, 0x05, 0x07– 0x41 这个范围留给用于requestSeed的sub-function;

0x04, 0x06, 0x08– 0x42 这个范围留给用于sendKey的sub-function。

具体选择哪对值,由整车厂自己定义。整车厂也可以选择多对sub-function,用于不同等级的安全访问。

举例来说:

假设0x05用于requestSeed,0x06用于sendKey。

  1. 诊断仪发送 27 05;
  2. ECU响应 67 05 01 0101(seed是 01 01 01);
  3. 诊断仪发送 27 06 02 03 04(key值是02 03 04,seed是 01 01 01,假设本地密码为01 02 03,而算法就是将密码与seed相加);
  4. ECU验证成功 67 06;

此时ECU就处于unlocked的状态了,那些被保护起来的诊断服务和诊断数据可以被操作了。通常来说,如果ECU重启,或者回到了default session,unlocked状态就失效了,如果要执行相关诊断服务,则需要再次执行上面描述的过程。

CommunicationControl (0x28)

该服务用于打开/关闭某些类别的报文的发送/接收。它通常在刷写软件或大量数据的时候使用,因为在刷软件或参数的时候并不需要ECU进行与通信相关的功能,将通信关闭之后可以把所有通信资源都留给软件或参数的下载,当下载过程完成之后再利用该服务将通信恢复即可。

0x28服务的格式如下图所示

第一部分即SID,一个字节,值为0x28;

第二部分是sub-function,即对ECU的通信进行哪种控制,具体包括 :

第三部分表明这条诊断请求要对哪种报文进行控制,长度为1个字节,定义如下表所示:

这个字节中最常用的就是低2 bit,0x1代表普通应用报文,0x2代表网络管理报文,0x3代表普通应用报文和网络管理报文。

第四部分是optional的,只有当sub-functional等于0x04或0x05时才需要使用。

举例来说:

28 01 01 表示激活应用报文的接收并关闭应用报文的发送(网络管理报文不受影响)。

28 00 01 表示激活应用报文的接收和发送(网络管理报文不受影响)。

TesterPresent (0x3E)

这个诊断服务的用处可以通过它的名字很明显地得知,即告知ECU诊断仪还在连接着。在$10中提到了关于session的部分,如果没有诊断命令的发送和接收,ECU将从non-default session中回退到default session, 0x3E就是用于使ECU保持在当前session。

这应该是UDS中最简单的一个诊断服务了,它永远只有两个byte,格式如下:

当sub-function是0x00时,ECU要给出response;

当sub-function是0x80时,ECU不需要给出response。

一般来说主机厂会为这个服务定义两个时间参数,一个参数用于规定自己的诊断仪发送0x3E服务的间隔,另一个参数用于定义ECU收不到0x3E服务的timeout时间。

ControlDTCSetting (0x85)

该服务用于控制ECU的DTC(diagnostic trouble code,故障诊断码)存储,这个服务常常和前面提到的28服务一起使用,比如,在开始写参数之前,为了获得更快的传输速度,我们用28服务把所有ECU的通信关闭了,但此时因为收到不到相关的报文,ECU会没有必要地存储很多DTC,这时如果我们使用85服务把ECU存储DTC的功能暂时性地禁止掉,则不会造成这种麻烦。

0x85服务请求的格式

第一部分即SID,一个byte,值为0x85;

第二部分是sub-function,即是打开还是关闭ECU的DTC存储,包括 :

0x01 on

0x02 off

第三部分是optional的,由各家自己定义,比如,可以用FF FF FF 来表示这条诊断命令针对所有的DTC。

ResponseOnEvent (0x86)

尽管诊断通信过程是问答式的,诊断仪发请求,ECU给响应。0x86服务算是一个例外,在ECU收到这条0x86服务之后,当DTC产生时,它会自动地上报DTC及相关环境数据,直到用另一条0x86服务来关闭ECU的这个行为。

该功能主要用于ECU的前期开发阶段,在售后和生产中是不会用到的,而且该服务的格式复杂(即可变的参数很多),执行它还分为好几个步骤,在这里就不过多叙述。

LinkControl (0x87)

这个服务用于转化ECU数据链路层和物理层的状态,比如,在高速CAN上的ECU正常通信速率是500kbit/s,但它同时也支持1M bit/s的波特率,如果需要刷写大量数据,便可以利用这条诊断服务让ECU以1M bit/s的波特率进行通信。

这个诊断服务的执行分为两个步骤:

验证ECU是否支持要调整到的目标波特率

让ECU的数据链路层和物理层转到目标波特率的通信状态

只有当第一个步骤验证通过了,第二个步骤才可以成功执行。

数据传输类服务

在数据传输类服务,0x22和0x2E成对使用,0x23和0x3D成对使用,这几个服务用于诊断数据的基本读写操作。0x24,0x2A,0x2C是一些特殊操作。

ReadDataByIdentifier (0x22)

$22,即读数据

l Request(请求):22+DID(Data Identifier,通常是两个字节)

l Response(响应):62+DID+Data

DID有一部分已经被ISO 14229-1规定了。比如0xF186就是当前诊断会话数据标识符,0xF187就是车厂零件号数据标识符,0xF188就是车厂ECU软件号码数据ID,0xF189就是车厂ECU软件版本号数据标识符。

举例来说:

22 F1 87 (读取零件号,DID=F1 87)

62 F1 87 XX YYZZ KK MM NN(给出零件号)

WriteDataByIdentifier (0x2E)

l Request(请求):2E+DID+Data

l Response(响应):6E+DID

注意,比如0xF186这个DID不支持直接写入数据,需要用$10来进行会话转换。也就是说,对于写数据的请求,一般来说需要在一个非默认会话,和解锁的状态下才能进行。

举例来说:

2E F1 87 XX YY ZZ KK MM NN(写入零件号)

6E F1 87(给出positive response)

ReadMemoryByAddress (0x23)

0x23服务的请求格式

第一部分固定为1个byte, 0x23;

第二部分是格式信息,长度为1个byte,高4 bits用于指示memorySize的长度(字节数),低4 bits用于指示memoryAddress的长度(字节数)。比如,如果这个值为0x46,则后面的memorySize为6个byte,memoryAddress为4个byte。

第三部分是memoryAddress信息,它的长度由第二部分的AddressAndLengthFormatIdentifier指示。

第四部分是memorySize信息,它的长度由第二部分的AddressAndLengthFormatIdentifier指示。

如果这条命令的格式是 23 22 xx yy aa bb,则它的含义就是,读取xx yy地址的长度为aa bb的数据。

WriteMemoryByAddress (0x3D)

了解了0x23的用法,0x3D的用法就很好理解了,它标识memoryAddress和memorySize的方法与0x23相同,只是在诊断命令最后再加上一段需要写入的数据。

存储数据传输服务

存储数据传输服务,用于操作DTC(diagnostic trouble code,故障诊断码)

在 ISO15031-6 中对 DTC 的格式有明确的定义,该规范中定义了 DTC 共由三个字节组成,如下图所示

DTC格式

字节1字节2字节3
诊断故障代码高字节诊断故障代码低字节诊断故障代码失效类型字节

在 ISO15031-6 中对 DTC 格式中的字节 1 与字节 2 也做了具体的定义,通过这个定义可以很方便确定记录的 DTC 属于车上的那种类型。

至此,DTC故障码的概念解释完毕,下面将展开关于存储传输类服务的解读:

这类服务主要涉及到两条诊断命令,分别是:

0x14:ClearDiagnosticInformation

0x19:ReadDTCInformation

这两条服务用于操作存储在ECU中的DTC,使用频率很高,而且它们比较好地体现了“诊断”两个字的含义。

ClearDiagnosticInformation(0x14)

这条诊断命令的格式比较简单,用法也很好理解,即删除存储在ECU中的DTC。

第一个字节就是SID了,后边的三个字节用于标识将要被删除的DTC种类,UDS规定用FF FF FF表示所有种类的DTC,由厂家自定义代表Powertrain、Chassis、Body、NetworkCommunication等种类DTC的值。

举例来说

Request:14+FF+FF+FF;(删除掉ECU中的所有DTC)

Response:54 ;

ReadDTCInformation(0x19)

这条指令用于读取存储在ECU中的DTC,0x19服务的sub-function代表了各式各样读取DTC的方法,UDS给19服务的sub-function从0x00到0x19进行了明确定义,这里介绍其中常见4种。

  • sub-function = 0x01(reportNumberOfDTCByStatusMask)

用于读取符合DTC状态掩码的DTC的数量,此时parameter为一个byte的Mask掩码,用于与DTC的Status进行“与”运算,而ECU返回的则是"与"运算之后结果不为0的DTC的数量。

DTC的Status用一个byte表示,其中的8个bit分别代表DTC的不同状态,比如,bit0 表示这个DTC是active的还是passive的,bit 4表示这个DTC是否已经被confirm了,如果DTC的状态是confirm,则说明该DTC已经被ECU存储下来了。

比如:19 01 08这个命令的用途,就是读取所有状态为confirm的DTC的数量。

  • sub-function = 0x02(reportDTCByStatusMask)

用于读取符合特定条件的DTC列表,此时parameter仍然为一个byte的Mask,用于与DTC的Status进行“与”运算,而ECU返回的则是"与"运算之后结果不为0的DTC列表。

比如19 02 01这个命令的用途,就是读取所有状态为active的DTC的数量。此时ECU返回的格式应该是59 02 01 XX XX XX 01 YY YY YY 09......。返回的DTC列表中的每个条目为4个字节,前三个字节用于标识DTC,比如 XX XX XX,最后一个字节用于标识DTC状态,比如01,表示DTC是active的,09表示DTC是active且confirm的。

  • sub-function = 0x06(reportDTCExtDataRecordByDTCNumber)

用于读取某个DTC及其相关的环境数据,此时parameter为4个byte,前三个byte用于标识我们要读取的DTC,第四个byte用于标识要读取的环境数据的范围,UDS规定使用FF来表示读取所有的环境数据,各厂家可以要根据自己的需求定义其他的值来代表要读取的环境数据的范围。环境数据包括DTC状态,优先级,发生次数,老化计数器,时间戳,里程等,厂家还可以根据自己的需求定义一些此DTC产生时的测量数据。

比如 19 06 XX XX XX FF就表示读取 XX XXXX这个DTC的所有环境数据,ECU的返回值应该是59 06 XX XX XX AA BB CC DD.....,其中AA BB CCDD...代表的就是XX XX XX这个DTC产生时所一起存储的环境数据。

  • sub-function = 0x0E(reportMostRecentConfirmedDTC)

sub-function = 0x0E时,不需要parameter。0x0E表示,要求ECU上报最近的一条被置为confirm的DTC。上文介绍过0x86服务,sub-function = 0x0E的19服务通常被作为参数传递给86指令,要求ECU在发生DTC存储的时候进行自动上报,即19 0E这两个字节的指令被嵌入到86服务的命令中。这条命令在开发阶段会用到,比如验证某个故障路径是否生效。

  1. 小结

本文概述了UDS协议,交互方式及部分诊断服务内容(包括诊断和通信管理类”“数据传输类”“存储数据传输”)。

后续将继续更新余下的诊断服务内容(包括IO控制,例程控制,上传与下载)及其他相关内容,敬请期待!


http://chatgpt.dhexx.cn/article/qftCbjdv.shtml

相关文章

UDS协议(史上最全)

UDS协议 UDS应用层协议解读(上) ISO 15765-3主要包含以下内容 应用层时间参数 P2CAN_ClientP2*CAN_ClientP2CAN_ServerP2*CAN_ServerP3CAN_Client_PhysP3CAN_Client_Func会话层时间参数 S3Client 当ECU处于非默认会话模式时,test端会周期性地…

八叉树地图

点云地图不能用于导航,八叉树地图可以用于导航八叉树:从一个节点展开成八个子检点,整个空间从最大空间细分到最小空间的过程 octomap 八叉树建立的地图由很多小方块组成,分辨率较高的时候,方块很小;分辨率…

八叉树(Octree)

转自:http://www.cnblogs.com/21207-iHome/p/7098000.html 八叉树(Octree)是一种用于描述三维空间的树状数据结构。想象一个立方体,我们最少可以切成多少个相同等分的小立方体?答案就是8个。再想象我们有一个房间&…

八叉树及应用

八叉树及应用 八叉树的定义如何搭建一颗八叉树八叉树的作用八叉树的实际应用 上一次介绍了KD树及应用,这次介绍一下八叉树,主要从定义、结构、作用及应用几个方面进行理解。 八叉树的定义 八叉树是在描述三维空间坐标场景中常用的一种数据结构。如下图所…

八叉树场景管理

目录 什么是八叉树(八叉树的数据结构)八叉树的图例八叉树的实现算法八叉树的场景管理器代码实现八叉树的应用场景 1.什么是八叉树——八叉树的数据结构 八叉树是一个树形结构,它的特点就是每个节点正好拥有八个子节点。它的这个结构特点正好能把空间立方体平均分成对…

基于八叉树的空间划分及搜索操作

基于八叉树的空间划分及搜索操作 原理CodeCmakeList.txtCPP体素 近邻 搜索K 近邻 搜索半径内 近邻 搜索 Result 原理 建立空间索引在点云数据处理中有着广泛的应用,常见的空间索引一般 是自顶而下逐级划分空间的各种空间索引结构。 比较有代表性的包括 BSP树KD树K…

基于C++的八叉树颜色删减实验

基于八叉树颜色删减实验 一、实验目的及要求 实现真彩色到256色的颜色转换算法 提供的代码: main.cpp :提供了主控函数main ,八叉树类octTree 和八叉树节点结构octNode 。 代码的编译: 由于需要使用bmp的信息头和文件头结构…

八叉树 java_图像八叉树量化讲解 Java版本

这篇文章主要讲解八叉树算法的原理,并用java进行实现 1.算法原理 八叉树最早是在1988年,由 M. Gervautz 和 W. Purgathofer 提出,该算法的最大优点是效率高,占用内存少。在图像量化中的思路是,图像rgb通道的值均为8比特…

详解八叉树地图

个人博客:http://www.chenjianqu.com/ 原文链接:http://www.chenjianqu.com/show-102.html 八叉树地图 八叉树地图(OctoMap)就是一种灵活的、压缩的、又能随时更新的地图。八叉树示意图如下: 一个大立方体不断地均匀分成八块,直…

PCL可视化八叉树格网

1 原理 八叉树其实是一种特殊的由上至下的体素,其构造原理在这里不再进行赘述,详细的构造方式可参考博客:https://blog.csdn.net/qq_32867925/article/details/109094719 有时候为了将点云、构造的层次八叉树需要进行可视化,便于…

松散八叉树

1八叉树简述 1.1定义1.2数据1.3树的建立 1.3.1计算包围体的大小与中心点1.3.2判断物体所属的包围盒2松散八叉树 2.1松散八叉树的建立 八叉树简述 定义 八叉树是一种对三维世界进行场景管理的理想的空间数据结构。八叉树中根节点包含一个立方体包围盒。每个非叶子节点都拥有八…

八叉树学习

八叉树学习 八叉树结构八叉树的存储结构1. 规则八叉树:2.线性八叉树:3.一对八式八叉树 参考网站 八叉树结构 八叉树结构是由 Hunter 博士于1978年首次提出的一种数据模型。八叉树结构通过对三维空间的几何实体进行体元剖分,每个体元具有相同…

PCL中的八叉树

目录 (1)什么是八叉树 (2)PCL中八叉树的体素形成和PCL中基于八叉树的点云压缩 (3)基于八叉树的k邻域搜索、半径搜索和体素近邻搜索 (4)基于八叉树和基于 kd-tree 的k邻域搜索、半…

八叉树 java_java简单实现八叉树图像处理代码示例

一晃工作有段时间了,第一次写博客,有点不知道怎么写,大家将就着看吧,说的有什么不正确的也请大家指正。 最近工作中用到了一个图像压缩的功能。找了一些工具,没有太好的选择。最后选了一个叫jdeli的,奈何效…

八叉树

http://hi.baidu.com/onlywater/blog/item/905c5e162ed18f4021a4e9c1.html 一、八叉树基本原理: 用八叉树来表示三维形体,并研究这种表示下的各种操作以及应用,是进入80年代后开展起来的。这种方法,既可以看成是四叉树方法在三维…

Octree(八叉树)

1. 算法原理 八叉树(Octree)是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,将八个子节点所表示的体积元素加在一起就等于父节点的体积。八叉树是四叉树在三维空间上的扩…

【PCL自学:ocTree】八叉树(octree)的原理及应用案例(点云压缩,搜索,空间变化)

PCL中八叉树(octree)的原理及应用案例 一、什么是八叉树ocTree?1.八叉树原理 二、八叉树应用案例1.点云压缩2.用八叉树进行空间划分和搜索操作3.无序点云数据的空间变化检测 一、什么是八叉树ocTree? 1.八叉树原理 上世纪80年代&…

十进制小数化为二进制小数的方法是什么_十进制转成二进制的两种方式

第一种:用2整除的方式。 用2整除十进制整数,得到一个商和余数;再用2去除商,又会得到一个商和余数,如此重复,直到商为小于1时为止,然后把先得到余数作为二进制数的低位有效位,后得到的…

Python 利用内置函数把二进制小数转换为十进制

如果需要把一个二进制整数转换为十进制整数,只需要简单的一行: int(1101,2) 但如果有一个二进制小数的话,就需要自己实现一个函数了。 不过,许多人是这样写的:(图片取自这里) 可是,由于python本身并不适…

[学习笔记] 二进制小数表示方法

文章目录 科学计数法二进制推广计算机中的小数EXCESS表示系统特殊情况举例(float)普通情况最大正实数普通情况最小负实数普通情况最小正实数特殊情况最大正实数 科学计数法 科学计数法想必大家都很熟悉了,往往通过如下形式表示一个实数&…