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

《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

相关文章:

  • ajax跨域原理
  • 红利窗口关闭?AI能否在安防开枝散叶
  • EntityFramework之领域驱动设计实践(六)(转)
  • Linux菜鸟级重点
  • LUN Mapping和ZONE在存储网络中的应用
  • Intel发布P4501数据中心超薄固态盘 3200MB/s、二代3D TLC
  • 深入分析 Java I/O 的工作机制
  • 微软延长Skylake平台支持Windows 7/8.1生命周期
  • vi 命令合集
  • 让小城市享受大城市的便利
  • linux下使用飞信机器人告警
  • 号外!微信企业版真的来了
  • VM Esx 4.1 虚拟机安装ocfs2
  • 《OpenStack实战指南》—— 1.3 OpenStack的功能与作用
  • 陀飞轮
  • express.js的介绍及使用
  • React as a UI Runtime(五、列表)
  • React系列之 Redux 架构模式
  • 初识 beanstalkd
  • 从重复到重用
  • 分布式事物理论与实践
  • 聊一聊前端的监控
  • 树莓派 - 使用须知
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​你们这样子,耽误我的工作进度怎么办?
  • #### go map 底层结构 ####
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (6)STL算法之转换
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (十八)SpringBoot之发送QQ邮件
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • ******之网络***——物理***
  • ***原理与防范
  • .jks文件(JAVA KeyStore)
  • .Net - 类的介绍
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET Core引入性能分析引导优化
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • //TODO 注释的作用
  • @Responsebody与@RequestBody
  • @RunWith注解作用
  • [20170713] 无法访问SQL Server
  • [Android Pro] AndroidX重构和映射
  • [C++]命名空间等——喵喵要吃C嘎嘎
  • [Contiki系列论文之2]WSN的自适应通信架构
  • [EULAR文摘] 脊柱放射学持续进展是否显著影响关节功能
  • [FROM COM张]如何解决Nios II SBTE中出现的undefined reference to `xxx'警告
  • [Golang]K-V存储引擎的学习 从零实现 (RoseDB mini版本)
  • [HOW TO]如何在iPhone应用程序中发送邮件
  • [HUBUCTF 2022 新生赛]
  • [leetcode 数位计算]2520. 统计能整除数字的位数