当前位置: 首页 > news >正文

[PICO VR眼镜]眼动追踪串流Unity开发与使用方法,眼动追踪打包报错问题解决(Eye Tracking/手势跟踪)

前言

最近在做一个工作需要用到PICO4 Enterprise VR头盔里的眼动追踪功能,但是遇到了如下问题:

  1. 在Unity里面没法串流调试眼动追踪功能,根本获取不到Device,只能将整个场景build成APK,安装到头盔里,才能在代码里调用眼动追踪功能。这使得每次修改代码都要打包一次apk安装到头盔里,十分不方便,难以调试。
  2. PICO VR 官方提供的Eye Tracking教程里,获取到的眼睛朝向和位置是相对于Head这个位置的,而不是相对于XR Origin下的Camera的位置,这使得API不能直接拿来使用。
  3. Unity在引入PICO VR眼动跟踪代码后,编译时点击"build and run"后,会报错“NullReferenceException: Object reference not set to an instance of an object

鉴于以上问题网络上均没有人进行解答,以及个人没能得到PICO官方的技术支持情况下(三周内发了2封技术工单邮件+2次催线上客服),遂打算自己捣鼓一下写篇教程。

(点名批评PICO官方的技术支持不回复邮件的问题,明明就几个特别简单的问题,但是官方承诺的3-5个工作日内回复并没有做到,等了三周一封邮件也没回,这个过程还问了客服,客服表示会催技术人员回复,但等了一周半也没看到,放弃了orz)

更新补充:据说在PICO企业版官网提交企业版工单能得到官方较快的回复。

1. 如何在代码里使用眼动跟踪,并转换成世界坐标 或 摄像机坐标系

首先,检查眼动追踪是否能正常工作:

void Start()
{CheckEyeTracking();}
private void CheckEyeTracking()
{//Start PICO Eye Tracking ServiceTrackingStateCode trackingState;trackingState = (TrackingStateCode)PXR_MotionTracking.WantEyeTrackingService();Debug.Log("告知PICO想要眼动跟踪服务 trackingState: " + trackingState.ToString());//Check Eye Tracking able or notEyeTrackingMode eyeTrackingMode = EyeTrackingMode.PXR_ETM_NONE;bool supported = false;int supportedModesCount = 0;trackingState = (TrackingStateCode)PXR_MotionTracking.GetEyeTrackingSupported(ref supported, ref supportedModesCount, ref eyeTrackingMode);Debug.Log("检查是否有眼动跟踪功能 trackingState: "+ trackingState.ToString()+"  code  "+ supported);// Get Eye Tracking Statebool tracking = true;EyeTrackingState eyeTrackingState = new EyeTrackingState();trackingState = (TrackingStateCode)PXR_MotionTracking.GetEyeTrackingState(ref tracking, ref eyeTrackingState);Debug.Log("获取当前眼动跟踪状态 trackingState: " + trackingState.ToString());// Start Eye Tracking//这里要严谨点的话,应该要加上if条件判断是否有眼动跟踪功能,再选择开启该功能EyeTrackingStartInfo info = new EyeTrackingStartInfo();info.needCalibration = 1;info.mode = eyeTrackingMode;trackingState = (TrackingStateCode)PXR_MotionTracking.StartEyeTracking(ref info);Debug.Log("开始眼动跟踪状态 trackingState: " + trackingState.ToString());//Get Eye Tracking Data//获取眼动跟踪数据EyeTrackingDataGetInfo eyeData = new EyeTrackingDataGetInfo();eyeData.displayTime = 0;eyeData.flags = EyeTrackingDataGetFlags.PXR_EYE_DEFAULT| EyeTrackingDataGetFlags.PXR_EYE_POSITION| EyeTrackingDataGetFlags.PXR_EYE_ORIENTATION;EyeTrackingData eyeTrackingData = new EyeTrackingData();trackingState = (TrackingStateCode)PXR_MotionTracking.GetEyeTrackingData(ref eyeData, ref eyeTrackingData);Debug.Log("eyeData:  "+ eyeData.ToString() + " TrackingData:  " + eyeTrackingData.ToString());}

接下来,每帧都获取眼动数据,并将眼睛位置和眼睛朝向数据转换成世界坐标

public Transform origin;//在Unity主界面把XR Origin拖进来即可
private Matrix4x4 headPoseMatrix,originPoseMatrix;
private Vector3 combineEyeGazeVector, combineEyeGazeOriginOffset, combineEyeGazeOrigin;
private Vector3 combineEyeGazeVectorInWorldSpace, combineEyeGazeOriginInWorldSpace;
void Update()
{GetEyeTrackingData();
}private void GetEyeTrackingData()
{//获取head的局部转世界矩阵,该矩阵点乘head局部坐标系下坐标,则能转换为世界坐标系下的坐标PXR_EyeTracking.GetHeadPosMatrix(out headPoseMatrix);	//获取双眼(取中间位置)位于Head坐标系下的朝向信息GazeVectorPXR_EyeTracking.GetCombineEyeGazeVector(out combineEyeGazeVector);//获取双眼(取中间位置)位于Head坐标系下的位置信息GazePointPXR_EyeTracking.GetCombineEyeGazePoint(out combineEyeGazeOrigin);//获取眼睛的世界坐标combineEyeGazeOriginInWorldSpace = originPoseMatrix.MultiplyPoint(headPoseMatrix.MultiplyPoint(combineEyeGazeOrigin));//获取眼睛的朝向信息combineEyeGazeVectorInWorldSpace = originPoseMatrix.MultiplyVector(headPoseMatrix.MultiplyVector(combineEyeGazeVector));//highlighArea是我添加的一个手电筒高亮区域,能让用户更直观地查看眼睛看向位置highlighArea.transform.position = combineEyeGazeOriginInWorldSpace ;//LookRotation默认是以z轴旋转,如果要以y轴旋转的话可以在后面加上 ,Vector3.uphighlighArea.transform.rotation = Quaternion.LookRotation(combineEyeGazeVectorInWorldSpace);
/*        RaycastHit hit;if (Physics.Raycast(highlighArea.transform.position, combineEyeGazeVectorInWorldSpace, out hit, 1000f)){highlighArea.transform.LookAt(hit.point);}*/
}

简易效果图(透明圈处是一个作为highlighArea的圆锥区域):
在这里插入图片描述

至此,便已经能获取到PICO VR里眼动追踪的位置和朝向信息。

2. "Build and Run"报错

引入EyeTracking代码后,发现Build and Run时会报以下错误:
在这里插入图片描述

在这里插入图片描述
这是因为run的话会导致Unity找不到可供眼动追踪的设备,导致编译报错。

解决方法,只点击Build,而不是Build and Run:
在这里插入图片描述
Build完后,打开Pico Developer Center,依次点击"应用管理"->“安装包”->“安装本地应用”:
在这里插入图片描述
选择build好的apk即可,后续便能直接在眼镜里运行:
在这里插入图片描述

3.眼镜内调试的Trick

对于这种要build到眼镜里才能调试的功能,可以利用Unity提高的UI->Text组件进行调试。

即,在Unity场景下创建一个UI->Text对象,然后把对象拖到下面脚本的GazeDebugText变量上,便能在眼镜里看到相应数据输出了

public TMP_Text GazeDebugText;
private void GetEyeTrackingData()
{GazeDebugText.text = combineEyeGazeOrigin.ToString("F3");//F3是指精确到小数点后3位
}

效果:
在这里插入图片描述

4.如何在Unity里串流调用眼动追踪功能

B站视频:使用PICO头显在VR串流环境下进行眼动追踪

我个人是在看了这个视频后才知道PICO VR也能在Unity下串流使用眼动跟踪功能,但我没有进一步深入探究,据该视频UP主表示,PICO neo3 pro eye是可以串流的,该方法理应也适用于其他头盔(带有企业串流功能的头盔)。

在此处也表达下对UP主的感谢,在后台私信耐心细致替我解答问题。

想要串流使用pico的眼动追踪功能,需要下载特定的串流软件和PICO系统版本。

4.1 串流工具准备

PC端我们要下载最新版本的PICO企业版串流工具(普通版的串流工具不知道可不可以):在这里插入图片描述
在PICO端上则是自动保持串流软件更新到最新版本即可。

在PC端下载好“企业串流”软件后,点击"设置"->“通用”:
在这里插入图片描述
把需要的功能都勾选上(默认是关闭状态):
在这里插入图片描述

business streaming安装后且打开眼动追踪功能后,sdk里会有一个用qt写的测试程序,可以试试看串流后眼动跟踪是否正常,测试程序不需要用steam,但是对头显的固件版本有要求:
在这里插入图片描述
点击get eye tracking(记住,一定要戴上头盔的情况下,盲点这个按钮,不如眼睛都不在头盔里面自然捕获不到数据),正常的话会显示如下数据:
在这里插入图片描述
如果这里显示ET Data 是 invalid的,那证明你没有戴上头盔后再点击get eye tracking,因为头盔没能捕捉到瞳孔数据,记住一定要先戴上头盔再盲点击按钮。

4.2 企业串流+OpenVR+SteamVR进行Unity开发

众所周知,任意VR头盔都能用SteamVR+OpenVR来开发VR应用,我们的PICO眼镜也可以,这里的“企业串流”只起到了传输EyeTrackingData的作用。我们如果要用到眼动追踪串流调试的话,就需要以OpenXR+SteamVR的方式进行开发,详细教程可以参考:知乎-Pico基于Unity XR Interaction Toolkit开发SteamVR串流应用 如果能正常串流到Unity界面,则我们进入下一步代码开发。

4.3 代码部分

接下来便是关键的部分,我们要在代码里引入企业版的PICO SDK并初始化(在你要用到Eye tracking代码最开始的地方引入即可,):

//引入 企业版串流SDK
private const string PXR_PLATFORM_DLL = "BStreamingSDK.dll";
//对 企业版串流SDK 进行初始化
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
private static extern int BStreamingSDK_Init(IntPtr userData);
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern int BStreamingSDK_Deinit();

此处的SDK跟我们平常开发PICO用的PXR SDK不一样,是为串流功能专门要用的SDK,该SDK会随business streaming一起安装,不需要你特定指明路径。而且当我们将项目build成apk安装包之后,调用的SDK是正常使用的,不用担心冲突问题等。

接下来便是获取眼部追踪数据/手势追踪数据即可:

//眼动追踪
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
private static extern int BStreamingSDK_GetEyeTrackingData(ref PxrEyeTrackingData etdata);//手势追踪
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
private static extern int BStreamingSDK_GetHandTrackerAimState(HandType hand, ref HandAimState aimState);
[DllImport(PXR_PLATFORM_DLL, CallingConvention = CallingConvention.Cdecl)]
private static extern int BStreamingSDK_GetHandTrackerJointLocations(HandType hand, ref HandJointLocations jointLocations);

此外,注意这里的PxrEyeTrackingData并不是SDK自带的类,而是需要我们自己在代码里创建的类,然后将其传入官方提供的函数来获取数据(手势追踪的Hand AimState等也是如此要自己创建类,详细部分可以向官方发送企业工单获取技术人员帮助),该类的定义如下所示:

public struct PxrEyeTrackingData
{public int leftEyePoseStatus;public int rightEyePoseStatus;public int combinedEyePoseStatus;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public float[] leftEyeGazePoint;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public float[] rightEyeGazePoint;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] combinedEyeGazePoint;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] leftEyeGazeVector;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] rightEyeGazeVector;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] combinedEyeGazeVector;public float leftEyeOpenness;public float rightEyeOpenness;public float leftEyePupilDilation;public float rightEyePupilDilation;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] leftEyePositionGuide;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] rightEvePositionGuide;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]public float[] foveatedGazeDirection;public int foveatedGazeTrackingState;
}

后续要注意到的点是,串流SDK里 CombinedEyeGazeVector Z轴是要取反的,与PICO Integration SDK不同:

PxrEyeTrackingData etData = new PxrEyeTrackingData();
var result = BStreamingSDK_GetEyeTrackingData(ref etData);
headPoseMatrix = Matrix4x4.TRS(userView.transform.position, userView.transform.rotation, Vector3.one);
var eyePoseStatus = etData.combinedEyePoseStatus;
var gazePosition = new Vector3(etData.combinedEyeGazePoint[0], etData.combinedEyeGazePoint[1], etData.combinedEyeGazePoint[2]);
var gazeVector = new Vector3(etData.combinedEyeGazeVector[0], etData.combinedEyeGazeVector[1], -etData.combinedEyeGazeVector[2]);
combineEyeGazeOrigin = gazePosition;
combineEyeGazeVector = gazeVector;combineEyeGazeOriginInWorldSpace = headPoseMatrix.MultiplyPoint(combineEyeGazeOrigin);
combineEyeGazeVectorInWorldSpace = headPoseMatrix.MultiplyVector(combineEyeGazeVector);
highlightArea.position = combineEyeGazeOriginInWorldSpace;
highlightArea.rotation = Quaternion.LookRotation(combineEyeGazeVectorInWorldSpace);

如果经过测试后,eye tracking data什么的没有问题,后续在Unity串流过程中使用Eye Tracking Dat并基于OpenXR进行应用调试与开发。

相关文章:

[PICO VR眼镜]眼动追踪串流Unity开发与使用方法,眼动追踪打包报错问题解决(Eye Tracking/手势跟踪)

前言 最近在做一个工作需要用到PICO4 Enterprise VR头盔里的眼动追踪功能,但是遇到了如下问题: 在Unity里面没法串流调试眼动追踪功能,根本获取不到Device,只能将整个场景build成APK,安装到头盔里,才能在…...

一周热门|比GPT-4强100倍,OpenAI有望年底发布GPT-Next;1个GPU,1分钟,16K图像

大模型周报将从【企业动态】【技术前瞻】【政策法规】【专家观点】四部分,带你快速跟进大模型行业热门动态。 01 企业动态 Ilya 新公司 SSI 官宣融资 10 亿美元 据路透社报道,由 OpenAI 联合创始人、前首席科学家 Ilya Sutskever 在 2 个多月前共同创…...

软考流水线计算

某计算机系统输入/输出采用双缓冲工作方式,其工作过程如下图所示,假设磁盘块与缓冲区大小相同,每个盘块读入缓冲区的时间T为10μs,由缓冲区送至用户区的时间M为6μs,系统对每个磁盘块数据的处理时间C为2μs。若用户需要…...

1份可以派上用场丢失数据恢复的应用程序列表

无论如何,丢失您的宝贵数据是可怕的。您的 Android 或 iOS 设备可能由于事故、硬件损坏、存储卡问题等而丢失了数据。这就是为什么我们编制了一份可以派上用场以恢复丢失数据的应用程序列表。 如果您四处走动,您大多会随身携带手机或其他移动设备。这些…...

MySQL Workbench 超详细安装教程(一步一图解,保姆级安装)

前言: MySQL Workbench 是一款强大的数据库设计和管理工具,它提供了图形化界面,使得数据库的设计、管理、查询等操作变得更加直观和便捷。本文将详细介绍如何在 Windows 系统上安装 MySQL Workbench。相信读者看这篇文章前一定安装了MySQL数…...

深度学习常见面试题及答案(16~20)

算法学习、4对1辅导、论文辅导或核心期刊以及其他学习资源可以通过公众号滴滴我 文章目录 16. 简述深度学习中的批量归一化(Batch Normalization)的目的和工作原理。一、批量归一化的目的1. 加速训练收敛:2. 提高模型泛化能力:3. …...

Packet Tracer - IPv4 ACL 的实施挑战(完美解析)

目标 在路由器上配置命名的标准ACL。 在路由器上配置命名的扩展ACL。 在路由器上配置扩展ACL来满足特定的 通信需求。 配置ACL来控制对网络设备终端线路的 访问。 在适当的路由器接口上,在适当的方向上 配置ACL。…...

Langchain-chatchat源码部署及测试实验

一年多前接触到Langchain-chatchat的0.2版本,对0.2版本进行了本地部署和大量更新,但0.2版本对最新的大模型支持不够好,部署框架支持也不好且不太稳定,特别是多模态大模型,因此本次主要介绍0.3版本的源码部署,希望对大家有所帮助。Langchain-chatchat从0.3版本开始,支持更…...

【Linux】线程(第十六篇)

目录 线程 1.线程基本概述: 2.线程类型: 3.线程间的共享资源与非共享资源 4.线程原语 1.线程创建函数 2.获取当前线程id的函数 3.回收线程资源 4.将线程设置为分离态 5.结束线程 6.退出线程 线程 1.线程基本概述: 是操作系统能够…...

2024华为杯研赛E题保姆级教程思路分析

E题题目:高速公路应急车道紧急启用模型 今年的E题设计到图像/视频处理,实际上,E题的难度相对来说较低,大家不用畏惧视频的处理,被这个吓到。实际上,这个不难,解决了视频的处理问题,…...

国内可以使用的ChatGPT服务【9月持续更新】

首先基础知识还是要介绍得~ 一、模型知识: GPT-4o:最新的版本模型,支持视觉等多模态,OpenAI 文档中已经更新了 GPT-4o 的介绍:128k 上下文,训练截止 2023 年 10 月(作为对比,GPT-4…...

Linux环境Docker安装Mongodb

Linux环境Docker安装Mongodb 环境要求拉取指定版本镜像创建映射目录(相当于数据存放于容器外,容器被删除不会影响数据)启动容器 进入mongo命令行为指定db创建新用户查看mongodb的容器id进入命令行查看所有db切换db为指定db创建新用户使用新账…...

PyTorch 池化层详解

在深度学习中,池化层(Pooling Layer)是卷积神经网络(CNN)中的关键组成部分。池化层的主要功能是对特征图进行降维和减少计算量,同时增强模型的鲁棒性。本文将详细介绍池化层的作用、种类、实现方法&#xf…...

Intel架构的基本知识

1.字节序 CPU的字节序分为LittleEndian和BigEndian。 所谓Endian,就是多字节数据在内存中的排列方式。 例如,假设有一个整数0x11223344: LittleEndian的排列方式是,从内存的低地址开始,依次存放 0x44 0x33 0x22 0x11; BigEndian的排列方式是,从内存的低地址开始,依…...

Element Plus 中Input输入框

通过鼠标或键盘输入字符 input为受控组件,他总会显示Vue绑定值,正常情况下,input的输入事件会正常被响应,他的处理程序应该更新组件的绑定值(或使用v-model)。否则,输入框的值将不会改变 不支…...

大模型中常见 loss 函数

loss 函数 首先,Loss 是允许不降到 0 的,模型计算的 loss 最终结果可以接近 0。 可以成为 loss 函数的条件## 常用 loss 以下函数调用基于 Pytorch,头文件导入: import torch.nn as nn 均方差(MSE) nn.…...

(十六)Ubuntu 20.04 下搭建PX4+MATLAB 仿真环境(HITL)

在文章(十五)Ubuntu 20.04 下搭建PX4MATLAB 仿真环境我们学习了如何配置仿真环境,在本节,主要进行HITL的仿真环境搭建。 根据(十五)Ubuntu 20.04 下搭建PX4MATLAB 仿真环境完成配置到如下界面:…...

Matlab simulink建模与仿真 第十七章(补充离散库和补充数学库)

参考视频:simulink1.1simulink简介_哔哩哔哩_bilibili 一、补充离散库和补充数学库中的模块概览 1、补充离散库 注:每个版本的补充离散库不一定相同,也不是每个版本的库都有如上所有模块。 2、补充数学库 二、离散直接传递函数Ⅱ模块 1、…...

Android Glide:让图片加载从未如此简单

在 Android 开发中,图片加载一直是一个关键环节。无论是从网络还是本地加载图片,都需要考虑到性能、内存管理和用户体验等多个方面。而在这方面,Glide 成为了众多开发者的首选库之一。本文将带你深入了解 Glide 的强大之处,并介绍如何在项目中快速集成和使用 Glide。 为什…...

YOLOv9改进策略【注意力机制篇】| 2024 SCSA-CBAM 空间和通道的协同注意模块

一、本文介绍 本文记录的是基于SCSA-CBAM注意力模块的YOLOv9目标检测改进方法研究。现有注意力方法在空间-通道协同方面未充分挖掘其潜力,缺乏对多语义信息的充分利用来引导特征和缓解语义差异。SCSA-CBAM注意力模块构建一个空间-通道协同机制,使空间注意力引导通道注意力增…...

Obsidian 全部笔记共享配置文件,obsidian仓库-文件夹配置统一化

obsidian仓库-文件夹配置统一化 在每次新建obsidian仓库(vaults)时,仓库的主题和快捷键等都需要重新设置,这是因为每次创建新的仓库时 新仓库的配置文件都是默认配置但是如果通过复制粘贴旧配置文件来达到新仓库的配置和旧仓库一致的话,无法…...

c++可视化打印树

#include <iostream> #include <string>// 定义节点结构体 struct Node {std::string data;Node* left;Node* right;Node(const std::string& data) : data(data), left(nullptr), right(nullptr) {} };// 递归打印树 void printTree(Node* root, std::string …...

ElementUI 快速入门:使用 Vue 脚手架搭建项目

文章目录 一 . ElementUI 的基本安装1.1 通过 Vue 脚手架创建项目1.2 在 vue 脚手架中安装 ElementUI1.3 编写页面 ElementUI 是 Vue.js 的强大 UI 框架&#xff0c;让前端界面开发变得简单高效。本教程将带你从安装到实战&#xff0c;快速掌握 ElementUI 的核心技巧。 核心内容…...

算法打卡:第十一章 图论part02

今日收获&#xff1a;岛屿数量&#xff08;深搜&#xff09;&#xff0c;岛屿数量&#xff08;广搜&#xff09;&#xff0c;岛屿的最大面积 1. 岛屿数量&#xff08;深搜&#xff09; 题目链接&#xff1a;99. 岛屿数量 思路&#xff1a;二维遍历数组&#xff0c;先判断当前…...

广度优先搜索算法及其matlab程序详解

#################本文为学习《图论算法及其MATLAB实现》的学习笔记################# 算法用途 广度优先搜索算法的应用 算法思想 广度优先搜索算法的步骤: ①,标号,令。 ②当所有标号为 的、与顶点 相关联的边的端点都已标号时,则停止;否则,把与 相关联的边的未标号的…...

力扣 438找到字符串中所有字母异位词

https://leetcode.cn/problems/find-all-anagrams-in-a-string/ 题目描述 题目分析 异位词所表示的空间 P \text{P} P 即一字符串的所有排列,记 s i \bold{s_i} si​为以 s [ i ] s[i] s[i]开头的长度为 plen \text{plen} plen的 s s s子串 故本题可理解为求解 A n s Ans Ans…...

图像滤波---各项异性扩散滤波使用笔记及代码

图像滤波---各项异性扩散滤波使用笔记及代码 一、文章内容介绍二、各项异性扩散滤波和各项同性滤波1、各项同性滤波2、各项异性扩散滤波3、各项异性和各项同性的对比 三、各项异性扩散滤波的原理介绍四、各项异性扩散滤波公式五、公式中的参数使用说明1、扩散速率 λ \lambda λ…...

用Go语言构建健壮的并发系统:深入理解错误传播与处理

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在当今的软件开发中,构建并发和分布式系统已经成为常态。然而,在这些系统中,错误的发生频率高且定位困难。如果我们能够深入考虑错误如何在系统中传播,以及最终如何呈现给用户,那么我们就能为自己、团队和用…...

掌握C#中的动态规划技术

C# 中的动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种在数学、计算机科学和经济学中使用的&#xff0c;通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划通常用于优化问题&#xff0c;特别是那些具有重叠子问题和最优子结构性质的问题…...

C语言进阶【5】---数据在内存中的存储【2】(小数存储很难吗?)

本章概述 本章引要练习 浮点数的存储浮点数的取出小补充题目解析彩蛋时刻&#xff01;&#xff01;&#xff01; 本章引要 常见的浮点数&#xff1a;3.1415&#xff0c;1E10等。其中&#xff0c;1E10是科学计数法的形式&#xff0c;它也就等于1*10^10。小数数据类型&#xff1…...