程式扎記: [ Ruby Gossip ] Basic : 內建型態與操作 - 數值型態

標籤

2014年10月4日 星期六

[ Ruby Gossip ] Basic : 內建型態與操作 - 數值型態

Source From Here
Preface
在 Ruby 中,數值都是 Numeric 的子類別實例,Numeric 的子類別有 Integer 代表整數、Float 代表浮點數,Integer 又有代表固定長度整數的 Fixnum 與超長整數的 Bignum


數值型態
在 Ruby 中,所有的資料都是物件,但可以使用實字(Literal)方式來撰寫表示數值,直接寫下一個整數值,預設是十進位整數,如果要撰寫二進位實字,則在數字前前 0b,如果要撰寫八進位實字,則在數字前置 0,之後接上1到7的數字,如果要撰寫十六進位整數,則以 0x 開頭,之後接上1到9、A到F。例如:
>> 10
=> 10
>> 0b10
=> 2
>> 010
=> 8
>> 0x10
=> 16

Fixnum 可容納的長度依機器而有所不同,如果撰寫的整數超出 Fixnum 可容納的長度,會自動轉換為 Bignum,所以基本上不用特別在意兩者的差別:
>> 1.class
=> Fixnum
>> 1111111111111111111111111111111111111111111111111111111111111.class
=> Bignum

可以使用字串、浮點數的 to_i 方法建立整數,如果是字串,to_i 可以指定以二進位、八進位或十六進位將字串代表的數值傳回,事實上,你可以在呼叫 to_i 時,指定2到36作為基底:
>> "10".to_i
=> 10
>> 3.14.to_i
=> 3
>> "10".to_i(2)
=> 2
>> "10".to_i(8)
=> 8
>> "10".to_i(16)
=> 16
>> "10".to_i(17)
=> 17

兩個整數相除,結果仍會是整數,如果想要有浮點數結果,則其中一個運算元必須是浮點數。例如:
>> 10 / 3
=> 3
>> 10.0 / 3
=> 3.33333333333333
>> 10 % 3
=> 1

在上例中,/是除法操作,%則是取得除法後的餘數。除了/與%之外,+、-、*等都可以運用在數值上,另外還有**次方運算。例如要計算2的100次方:
>> 2 ** 100
=> 1267650600228229401496703205376

可以直接寫下3.14這樣的數值作為浮點數,它們會是Float實例,可以使用3.14e-10這樣的表示法。例如:
>> 3.14
=> 3.14
>> 3.14e-10.class
=> Float

類似地,也可以使用整數、字串的to_f方法建立浮點數。例如:
>> "3.14159".to_f
=> 3.14159
>> "2.1e-10".to_f
=> 2.1e-010

使用浮點數,同樣要注意浮點數精度問題,例如:
>> 1.0 - 0.8
=> 0.19999999999999996
>> 7.3 - 7.2 == 0.1
=> false
>> 7.3 - 7.2
=> 0.0999999999999996
>> 1.2 - 1.0 - 0.2 == 0.0
=> false
>> 1.2 - 1.0 - 0.2
=> -5.55111512312578e-017

開發人員基本上都要了解CPU處理浮點數的設計原理,如果你要精確的結果,那麼可以使用 bigdecimal 中的 BigDecimal 類別。例如:
>> require "bigdecimal"
=> true
>> a = BigDecimal.new("7.3")
=> #
>> b = BigDecimal.new("7.2")
=> #
>> r = BigDecimal.new("0.1")
=> #
>> a - b == r
=> true
>> (a - b).to_f
=> 0.1

這解決了問題,但寫法較為冗長,可以要求 bigdecimal 中的 util 特性,這會為 Float 增加 to_d 方法,可以直接取得BigDecimal實例。例如:
>> require "bigdecimal/util"
=> true
>> 1.2.to_d
=> #
>> 1.2.to_d - 1.0.to_d - 0.2.to_d == 0.0.to_d
=> true
>> (1.2.to_d - 1.0.to_d - 0.2.to_d).to_f
=> 0.0


沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!