Ruby即时编程——(二)数据类型(数字)

这次谈一谈Ruby的数据类型。

Ruby和Python是很相像的编程语言,数据类型有很多相通的地方,如果你对Python语言非常熟悉,学习Ruby的数据类型也不会困难。

一、数字

整数(Integer)

整数的存储一般占4个字节,而对Ruby来说,只要整数的范围在[2-31,231),即不越界的话,它就属于Fixnum类型,只要超出了这个范围,Ruby会将数字类型自动转换为Bignum,范围[2-63,263)
以上是我在教程里看的,随后自己试了一下:

  b=2**16
  puts b,b.class
  b*=2**31
  puts b,b.class
  b**=31
  puts b,b.class

输出为:

65536
Integer
140737488355328
Integer
3987527419489428978934891797539519074407964567436787186133619573501046471683744380659059161937985807259468675374073145280737497721642052937815042118700682845870910169347677909227832368695028770450412842403709263345644496696985054600802825392442509910854943490420673962888628144965097175804215761432440180478119397118650550445707581358533929378076799381878425215674358616643302551330255407000153121771310799585481738504362758992372927823872
Integer

(其实并没有看出来什么区别,而且数字支持的范围也不仅仅是[2-63,263))

又看了这个链接,相同的输入输出了不同的东西
https://blog.csdn.net/ruby_cn/article/details/197985

最后查了一下是ruby版本的问题。在ruby2.2的官方文档中还有Fixnum和Bignum的类,现在最新的2.6.2版本中已经把它们去掉了。

那么我们以最新的版本为准,我的理解是这样的:

  1. 整数类Integer不可再分,支持任意大小和正负
  2. ruby为Integer变量自动分配存储空间,数值增减,数值空间也会随之增减。具体见代码:
1.size               #=> 8
-1.size              #=> 8
2147483647.size      #=> 8
(256**10 - 1).size   #=> 10
(256**20 - 1).size   #=> 20
(256**40 - 1).size   #=> 40

整数使用部分:
几种常见的整数应用实例:

1_234                # 带有下划线的十进制,_对数值没有用,可以作为标记(比如千分符)用
0377                 # 八进制
0xff                 # 十六进制
0b1011               # 二进制
"a".ord              # "a" 的字符编码
?\n                  # 换行符(0x0a)的编码

还有一点需要提的是:Integer可以取二进制位的值哦

p 3[0]  #相当于3%2
=>1
print 11[0],11[1],11[2],11[3],11[4],11[-1] #负数index全部返回0,没有用处
=>110100

小数

下面我说的有关小数范围的内容可能很细,读者可以略过,去读小数的使用部分。这里跳转

首先,我们必须了解: 计算机在存储一个小数的变量时是以二进制形式存储的,所以在小数约进约出的时候,计算机也会按照二进制计算。脱离二进制,空谈小数的约位是没有意义的。

比如下面这个简单的程序要脱离二进制解释就很难说通,为什么小数位是从0到不是0再到是0?

print ("%.70f"%0.1)
=> 0.1000000000000000055511151231257827021181583404541015625000000000000000

用二进制的思维去想,0.1实际上是二进制0.000(1100)的循环,Ruby保留了若干个二进制位,根据余位的多少进行进位或者是借位。再转化为十进制的时候,就会有小数点后面一定范围内的误差。
前面有零是因为前面计算都是正确的,后面是零是因为:由于除以2-n不管n有多大总会被除尽,二进制转化为十进制后不会出现循环

那么Ruby保留位数是多少呢?通过实验来证明一下:

a=1+1.0/2**52
puts ("%.60f"%a) 
=> 1.000000000000000222044604925031308084726333618164062500000000
a=1+1.0/2**53
puts ("%.60f"%a)
=> 1.000000000000000000000000000000000000000000000000000000000000
a=0.5+1.0/2**53
puts ("%.60f"%a)
=> 0.500000000000000111022302462515654042363166809082031250000000
a=1.5+1.0/2**53
puts ("%.60f"%a)
=> 1.500000000000000000000000000000000000000000000000000000000000
a=-1+1.0/2**53
puts ("%.60f"%a)
=> -0.999999999999999888977697537484345957636833190917968750000000

可以看出,Ruby保留小数时,主要看的是有效数字的部分。二进制有效数字部分为:
[-253,253-1)

所以会出现这样尴尬的情况:

a=1111111111111111111.1
puts ("%.3f"%a)
=> 1111111111111111168.000

既然小数的保留是看有效数字位数,科学记数法的指数自然也需要限制范围:

a=1.0*2**(2**10-1)
puts ("%.3f"%a)
=> 898846567431157...12068608.000
a=1.0*2**(2**10)
puts ("%.3f"%a)
=> Inf
a=1.0*2**(-0b10000110010)
puts ("%.1050f"%a)
=> 0.000...0000000556268464626800345...821289062500000000000000000000000000
a=1.0*(2**(-(0b10000110011)))
puts ("%.1050f"%a)
=> 0.000...0

可见,指数范围是[-0b1000110010,2**10),?搞不懂为什么范围这么奇怪,欢迎留言批评指正。

小数使用部分:

%

%运算符在小数中仍然可以使用:

a=3.4%2
puts (a)
=> 1.4
a=3.4%1.1
puts (a)
=> 0.09999999999999964
a=-3.4%(-1.1)
puts (a)
=> -0.09999999999999964
a=3.4%(-1.1)
puts (a)
=> -1.0000000000000004

用法自己体会。

rationalize
0.3.rationalize          #=> (3/10)
1.333.rationalize        #=> (1333/1000)
1.333.rationalize(0.01)  #=> (4/3)

这里0.01参数是指1.333-0.01<=4/3<=1.333+0.01

round

默认四舍五入,即half: :up,也可以指定half。
half: :even是遇到.5会约到最近的偶数

2.5.round(half: :up)      #=> 3
2.5.round(half: :down)    #=> 2
2.5.round(half: :even)    #=> 2
3.5.round(half: :up)      #=> 4
3.5.round(half: :down)    #=> 3
3.5.round(half: :even)    #=> 4
(-2.5).round(half: :up)   #=> -3
(-2.5).round(half: :down) #=> -2
(-2.5).round(half: :even) #=> -2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值