设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2547|回复: 3
打印 上一主题 下一主题

[已经解决] 关于Float类型与Fixnum类型的指针

[复制链接]

Lv3.寻梦者

孤独守望

梦石
0
星屑
3132
在线时间
1535 小时
注册时间
2006-10-16
帖子
4321

开拓者贵宾

跳转到指定楼层
1
发表于 2010-8-20 11:04:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
  1. # Float
  2. a = 3.0/5.0
  3. b = 3.0/5.0
  4. c = b
  5. p a.__id__,b.__id__,c.__id__
  6. p a - b == 0,a == b
  7. # Fixnum
  8. a = 10/5
  9. b = 10/5
  10. c = b
  11. p a.__id__,b.__id__,c.__id__
  12. p a - b == 0,a == b
复制代码
代码如上。发现浮点数是指针型,每次即使值相同也不返回同一个对象,而Fixnum则全然不同。
通过解析法亦可发现,在Ruby的Marshalling过程中,Float占用一个引用位置,而Fixnum则不占用。
求解。如能说明Fixnum(value class)的工作原理更佳。

总括:为什么Float是引用类,而Fixnum是值类?
菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客

Lv2.观梦者

旅之愚者

梦石
0
星屑
255
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

2
发表于 2010-8-20 11:16:42 | 只看该作者
回复 IamI 的帖子
不是都是值类么,Float似乎是精确度的缘故所以不相等
   

点评

在 Ruby 里 Fixnum 是直接数据,但 Float 不是  发表于 2010-8-20 11:35
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
283
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

3
发表于 2010-8-20 11:21:15 | 只看该作者
浮点数的相等判断是需要一个精度问题的。

  1. #define ZERO 10^(-10)

  2. float a,b;
  3. if(a - b < ZERO)
  4.   return true;
  5. else
  6. retrun false;
复制代码

点评

大约就是相当于指针吧,GC类好像有个类方法可以根据id返回object  发表于 2010-8-20 11:34
__id__ 是咱我都没弄明白~~~  发表于 2010-8-20 11:24
- -貌似II姐的a==b返回true。很奇怪fixnum的__id__返回一位数- -  发表于 2010-8-20 11:23

《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
4
发表于 2010-8-20 14:04:39 | 只看该作者
可能有以下几个原因:
1、在 32 位选址的 CPU 架构下,一个指针占用 32 位;Fixnum 的表示方法是 31 位 2's complement 补码形式;Float 的表示方式是本地的双精度浮点类型,大部分平台下使用的是 IEEE-754 标准,需要(但不一定是) 64 个字节。所以 Fixnum 可以作为直接值直接保存在 32 位的指针本身,而 64 位的 Float 却不行
2、整数作为直接值可以减少内存消耗——引用类型需要频繁进行堆内存操作,而在有垃圾回收机制的高级语言里,为了有效地分配和回收内存,堆通常是链式结构,垃圾回收器要频繁地查找、删除、插入、合并可用的内存节点并归组到一起以减少内存碎片,显然链式堆的任何内存操作都注定慢于连续内存结构(数组结构)的栈内存操作(VALUE 指针是在栈上)
3、虽然在计算机领域里定点数和浮点数的集合都是离散的,但浮点数集合的大小远远大于定点数集合。对于定点数,我们可以用某种算法给每个定点数一个固定的 object_id,而如果要让每一个可表示的浮点数也有这样的固定 object_id,其开销是不堪设想的。实际在应用的时候,很少会出现两个完全相同的浮点数的场合,从这一点上来看似乎也没有必要让浮点数拥有整数、符号、字符串那样的“扣留”机制

Fixnum 的工作原理:
Fixnum 和 NilClass、TrueClass、FalseClass 都是 Ruby 中的直接类型,这些类型的数据不会以复式结构体来表示,而是直接保存在了 VALUE 型指针里
Ruby 舍弃了 VALUE 的最低位作为“定点数标志位”,指定了这个数据是否是 Fixnum,所以在 Ruby 中 Fixnum 只有 31 位(VALUE 的值至少有 32 位),并且是被整体左移了一位,也就是数据存储在高 31 位中
与之平行存在的其它三种直接值类型分别是如此存储的:
VALUE 的值如果是 0b0000,那就是 false;如果是 0b0010,那就是 true;如果是 0b0100,那就是 nil;符号类型也有一个标志掩码 0x0e,即最低 8 位(最低字节)如果是 0b00001110 的话 VALUE 表示的就是一个符号类型。可以看出以上各项之间并没有交集
其余的引用类型,由于其本身是复式的结构体数据( 由 RBasic 衍生出来的结构体),所以是由 VALUE 这个指针来维护其地址的,由于内存对齐机制,无论如何这些结构体的首地址都必然是 4 的倍数,即最低两位为 0,所以引用类型的地址也不会和直接值的表示方式产生冲突
至于 object_id,则是直接返回 VALUE 的值。Fixnum 的最低位是 1,所以 Fixnum 的 object_id 必然是单数,且由于真实数据向左偏移了一位,object_id 和 数据本身的关系应该是 数据本身*2+1

评分

参与人数 1星屑 +700 收起 理由
IamI + 700 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-6 00:20

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表