《Core Data应用开发实践指南》一2.6 单精度浮点数与双精度浮点数

简介:

本节书摘来自华章出版社《Core Data应用开发实践指南》一书中的第2章,第2.6节,作者 (美)Tim Roadley,更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.6 单精度浮点数与双精度浮点数

对于属性来说,单精度浮点数(float)和双精度浮点数(double)这两种数据类型可以看作带小数点的非整数。它们都可以用来表示实数,但也都有一定的限制。单精度浮点数与双精度浮点数都使用以2为底的数制(也叫二进制),对CPU来说,这是一种原生的数制,它容易引起舍入误差。以1/5这个分数为例,如果采用十进制,那我们可以精确地将其写为0.2,但如果改用二进制,则只能表示出它的近似值。小数点后面的数位越多,精度就越高,表示出来的近似值也就越准确。高精度的数会占用更多内存,以保持其准确性。
与单精度浮点数相比,双精度浮点数所包含的二进制位(bit)的个数是它的两倍。单精度浮点数用32个二进制位来保存其数据,而双精度浮点数则占用64个二进制位。两者都采用科学计数法,也就是说,整个浮点数是由尾数和指数(表示2的多少次幂)组成的。双精度浮点数有64个二进制位,这意味着它的取值范围比单精度浮点数广,精度也比单精度浮点数高。
在iOS中,最大的单精度浮点数是340 282 346 638 528 859 811 704 183 484 516 925 440.000 000。单精度浮点数与双精度浮点数都有符号位(sign bit),所以,iOS中数值最小的单精度浮点数是340 282 346 638 528 859 811 704 183 484 516 925 440.000 000,而数值最大的双精度浮点数则比数值最大的单精度浮点数还要大出许多。本章最后有道习题,题中给出了一段代码,可以打印出各种数值数据类型的最小值与最大值。
在单精度浮点数和双精度浮点数之间取舍时,需要考虑正在配置的这个属性有何特点:它的最小取值和最大取值是多少?是不是真的需要超过7位的精度(单精度浮点数所提供的精度大约是7位)?如果不需要的话,那么在iOS平台上还是应该选用单精度浮点数,因为在64位的iPhone 5S出品之前,单精度浮点数这种数据类型更能够同底层的处理器相匹配。虽说使用一大批双精度浮点数特性看上去有些不太合理,但是要注意:数据库可能会导致程序在存储量方面的需求变得比想象中更大,因为它们可能要包含巨量的数据行。目前设备的能力和容量都很大,所以在大多数情况下,使用双精度浮点数其实也可以。如果追求浮点运算的速度,同时又不太关心精度,那么选用单精度浮点类型会更加合适。但在涉及“元”或“分”等货币单位的财务计算中,则不应该使用单精度浮点数或双精度浮点数,因为“舍入误差”会导致钱数出错!
根据实体来创建NSManagedObject子类时,如果实体中某个属性的类型为单精度浮点类型或双精度浮点类型,那么在创建好的子类里,相关特性的类型就会是NSNumber。

2.6.1 小数

在涉及货币或其他十进制运算的场合中,建议把属性的数据类型设为小数(decimal)。与二进制不同,对于CPU来说,十进制并不是原生的数制,这就意味着以小数来运算时,处理器会有比较大的开销。与单精度浮点数和双精度浮点数一样,小数也是由尾数(该尾数是个整数)、指数及符号组成的。虽说内存占用量和处理时间都比较多,但是小数的计算精度却很高。在这种数制里,0.1这个数就可以精确地表示出来了。如果属性的数据类型是小数,那么它就会把0.1存储为“1/10^1”。
与值最大的双精度浮点数值相比,值最大的小数其实并不算大,但它的精度却比双精度浮点数高出许多,而且在有些时候甚至是完全准确的。本章最后有道习题,题中给出的那段代码会以1/3这个数为例,打印出每一种“数值数据类型”所能达到的精度。
根据实体来创建NSManagedObject子类时,如果实体中某个属性的类型是小数类型,那么在创建好的子类里,相关特性的类型就会是NSDecimalNumber。在NSDecimal-Number上面执行计算时要注意:若想保留精度,则只能使用NSDecimalNumber内置的方法。

2.6.2 字符串

对于属性来说,字符串这种数据类型可以存放字符数组(array of character)或普通文本(plain old text)。作为Objective-C程序员,你应该已经对字符串相当熟悉了。根据实体来创建NSManagedObject子类时,如果实体中某个属性的数据类型是字符串,那么在创建好的子类里,相关特性的类型就会是NSString。

2.6.3 Boolean

对于属性来说,Boolean这种数据类型可用来存放“是”或“否”这两种值。根据实体来创建NSManagedObject子类时,如果实体中某个属性的数据类型是Boolean,那么在创建好的子类中,相关特性的类型就是NSNumber。若想从NSNumber中获取Boolean值,只需向该实例发送boolValue消息即可。而若想将NSNumber设置为某个Boolean值,则可使用numberWithBool方法。

2.6.4 日期类型

顾名思义,日期(date)这种数据类型就是用来在属性中保存日期和时间的。根据实体来创建NSManagedObject子类时,如果实体中某个属性的类型是日期类型,那么在创建好的子类中,相关特性的类型就是NSDate。

2.6.5 二进制数据类型

如果要保存照片、音频或其他由“0”、“1”二进制位所组成的连续BLOB,那么就应该把属性的类型设为二进制数据类型(Binary Data)。根据实体来创建NSManaged-Object子类时,如果某个属性的类型是二进制数据,那么在创建好的子类中,相关特性的类型就是NSData。至于如何在数据和NSData之间转换,那要依照具体存储的数据来定。二进制数据较常见的用途就是存储照片。存储照片时,可以通过UIImagePNGRepresentation()或UIImageJPEGRepresentation()来把UIImage转换成NSData。而获取照片时,则可以通过UIImage的类方法imageWith-Data把NSData转换为UIImage。二进制数据这种数据类型对于大文件来说比较合适,因为在属性的设置选项中,我们可以开启Allows External Storage,将其“无缝地”存储在数据库之外。启用了这个选项之后,Core Data就会自行判断是把文件存放在数据库内的效率高还是存放到数据库外的效率高。

2.6.6 可变类型

可变(Transformable)数据类型很适合用来把Objective-C对象存放到属性里。这种属性类型比较灵活,它可以存放任意类的实例。比方说,UIColor类的实例就可以保存在类型为可变类型的属性里。在根据实体来创建NSManagedObject子类时,如果实体中某个属性的类型是可变类型,那么在创建好的子类中,相关特性的类型就是id。若想把id对象放入存储区(或将其从存储区里取出来),则需借助NSValueTransformer类的实例或NSValueTransformer子类的实例。NSValueTransformer类可以在属性与NSData之间“透明地”执行转换。转换过程也比较简单,尤其当待存储的类本身已经实现了NSCoding协议时更是如此。假如实现了该协议,那么系统就会提供默认的transformer,而这个transformer自己知道如何“压缩”(archive)或“解压缩”(un-archive)相关的对象。
请按下列步骤修改Grocery Dude,以便配置其中的属性:

  1. 将name 属性的Type设为String。
  2. 将quantity 属性的Type设为Float。
  3. 在Item实体中添加名为photoData的属性,并将其Type设为Binary Data。这个属性用来存放货品照片的图像信息。(注意:目前并不启用Allows External Storage,本书后面再讲解何时启用它。)
  4. 在Item实体中添加名为listed的属性,并将其Type设为Boolean。这个属性用来表示货品是否已出现在购物清单中。
  5. 在Item实体中添加名为collected的属性,并将其Type设为Boolean。如果用户已经拿到了所要购买的货品,那么这个属性就是“真”,这表示该货品已经可以从购物清单中勾掉了。
    执行完上述步骤之后的数据模型如图2-4所示,现在每个属性的数据类型都已经配置好了。

image

为了给以后更加复杂的数据模型做准备,笔者在这里告诉你如何切换到图形化的编辑界面。要改变编辑器的显示模式,只需点击图2-5正下方的Editor Style按钮。图2-5左侧演示了编辑器在Graph风格下的样貌。

image

相关文章
|
存储 前端开发 PHP
构建一个简单的网站,包括用户注册、登录功能
构建一个简单的网站,包括用户注册、登录功能
1146 1
|
11月前
|
人工智能 计算机视觉
MangaNinja:开源线稿着色工具,自动匹配图像风格,一键快速上色
MangaNinja 是一款基于参考图像的线稿着色工具,通过创新的补丁重排模块和点驱动控制方案,实现精准颜色匹配和复杂场景处理,适用于漫画、插画和数字艺术创作。
554 10
MangaNinja:开源线稿着色工具,自动匹配图像风格,一键快速上色
|
11月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
547 3
|
网络协议 Unix
EOF到底是什么意思?
我们在使用C标准I/O时,经常会看到EOF这个概念,这里需要明确的是并不存在EOF这样一个字符,它只是一个控制条件。起初,我认为EOF就是字面意思即,到达了文件的结尾(End of File)。
1764 1
|
关系型数据库 MySQL Linux
CentOS 6.X 32位安装MySQL5.7保姆级教程
由于现在MySQL5.7针对32位Linux系统支持不是特别好,因此写下这篇文章进行一些教学(基于个人的方法,若有疑问欢迎讨论)
|
Java Unix Linux
M2_HOME还是MAVEN_HOME配置环境变量,有什么区别?
M2_HOME还是MAVEN_HOME配置环境变量,有什么区别?
772 0
|
数据可视化 关系型数据库 MySQL
Install MySQL Workbench 8.0 CE | MySQL
MySQL 数据库及服务的安装 MySQL 数据库,关系型数据库管理系统,一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据
731 0
Install MySQL Workbench 8.0 CE | MySQL
|
弹性计算
阿里云服务器免费试用1个月到期不用请释放否则会欠费
阿里云服务器免费试用1个月到期了怎么办?不要了就释放掉,想要继续使用可以将按量转为包年包月并续费
3786 0
阿里云服务器免费试用1个月到期不用请释放否则会欠费
|
自然语言处理 Windows
Notepad++官网地址及使用十六进制查看文件的详细教程
Notepad++官网地址及使用十六进制查看文件的详细教程
4185 0
Notepad++官网地址及使用十六进制查看文件的详细教程
|
XML 存储 设计模式
如何形成统一设计风格-实践篇
在上一篇《业务团队如何形成统一的设计风格》中,探讨了一种业务架构的设计规范,以期达到这些目标:用标准约束技术细节;用技术工具而非文档推行标准;持续重构而非造新轮子;重视业务建模。但通篇表述较为抽象。本篇将总结团队近来的架构演进工作,以更具体的技术细节,详细阐释该理念,作为“统一业务设计风格”的实践篇。文中详述了多个层面的设计规约和基于规约的搭建方式,并在末尾回答了上一篇的诸多疑问。
349 1

热门文章

最新文章