Kiểu dữ liệu Number trong Ruby (Kiểu số Integer, Float, …)

Trong bài này chúng ta sẽ tìm hiểu các kiểu dữ liệu number trong Ruby như kiểu số thực float, kiểu số nguyên interger, và nhiều ví dụ thực hành khác trong Ruby.

Để bắt đầu bất cứ một ngôn ngữ nào thì trước hết chúng ta cũng cần phải xem qua được những khái niệm cơ bản nhất như kiểu dữ liệu, method.. Trong mục này chúng ta sẽ tìm hiểu những khái niệm liên qua đến Datatypes and Object. Có rất nhiều các kiểu dữ liệu trong Ruby có thể liệt kể như Number, Text, Array, Hashes, Ranges, Symbol..

1. Giới thiệu

number png

Trước tiên, chúng ta cùng nhìn qua một bức ảnh tổng quát phân cấp các Number class. Trong Ruby bao gồm 5 class tượng trưng cho các kiểu dữ liệu số : Integer, Float, Complex, BigDecimal, Rational. Cả 5 class này đều được kế thừa từ là Numeric.

Bài viết này được đăng tại [kiso.vn]

Nhưng trong thực tế chỉ có 2 class được tích hợp sẵn trong Ruby đó là IntegerFloat, còn đối với các kiểu dữ liệu như Complex, BigDecimal, Rational không được tích hợp sẵn, chúng được sử dụng là một phần của standard library.

  • Integer: là kiểu dữ liệu number đơn giản nhất, là class để định nghĩa các số nguyên(1, 12, 100…). Integer là object của 2 class khác là FixnumBignum. Nếu một giá trị của số nguyên có giá trị khoảng 31 bits thì được coi là kiểu Fixnum. Còn đối với các số nguyên có giá trị lớn hơn thì thuộc class Bignum. Thông thường thì kiểu dữ liệu Fixnum sẽ phổ biến hơn là Bignum
  • Float: Đây là class để định nghĩa các số thực, sử dụng dấu phẩy động để định nghĩa.
  • Complex: Là class để định nghĩa số phức.
  • BigDecimal: Là class để định nghĩa số thực với độ chĩnh xác cao, được biểu diễn dưới các số thập phân
  • Rational: Là class định nghĩa phân số.
ClassVí dụ
Integer1
Fixnum1
Bignum11111111
Float2.1
Complex1 + 0i
BigDecimal3/4
Rational2.0
1.class
=> Integer

1.class.superclass
=> Numeric

1.1.class
=> Float

1.1.class.superclass
=> Numeric

Tất cả các giá trị thuộc Numeric Object đều là bất biến (giá trị không đổi)

2. Integer Literal

Như đã nói ở trên thì với giá trị số nguyên khoảng 32 bits hoặc 64 bits thì sẽ thuộc class Fixnum, ngược lại số nguyên đó sẽ thuộc class Bignum. Với kiểu dữ liệu Bignum thì với bất cứ giá trị với sizes nào thì sẽ đều thuộc kiểu dữ liệu này.

Khi một giá trị của Integer quá lớn nó sẽ tự động chuyển từ kiểu Fixnum sang kiểu Bignum.

Trong Ruby có một thứ khá hay ho là chúng ta có thể sử dụng ký tự underscore(dấu gạch dưới) để phân cách phần trăm phần nghìn với nhau. Trình thông dịch trong Ruby sẽ dịch cho chúng ta thành giá trị số nguyên.

1_000_000
=> 1000000

1_000_000.class
=> Integer

Để định nghĩa một số âm thì cũng chỉ đơn giản là thêm một dấu trừ đằng trước là được (-1).

3. Floating-Point Literals

Một floating-point literals trong ruby có thể hiểu là một đối tượng số thập phân với cú pháp kiểu số + dấu chấm động (floating-point) + một hoặc nhiều chữ số + hoặc option exponent(số mũ). Đối với exponent thì nó sẽ bắt đầu với ký tự e hoặc E tiếp theo đó là các giá trị số.

Cũng giống như integer literal, trong floating-point cũng sử dụng được dấu underscore để phân cách phần trăm phần nghìn.

0.0
-3.14
6.02e23 # Có nghĩa là 6.02 × 1023
1_000_000.01 # One million and a little bit more

Lưu ý :

Bắt buộc phải sử dụng một số nguyên đằng trước dấu chấm động và sau dấu chấm động để định nghĩa kiểu dữ liệu này, nếu không sẽ nhận ngay thông báo lỗi. Chúng ta khong thể sử dụng .1 để khai báo giá trị 0.1 như trong Javasript được, trong Ruby chúng ta phải khai báo rõ ràng nếu không sẽ nhận được thông báo lỗi

irb(main):001:0> .8
Traceback (most recent call last):
        3: from /home/quangphu/.rbenv/versions/2.6.5/bin/irb:23:in `<main>'
        2: from /home/quangphu/.rbenv/versions/2.6.5/bin/irb:23:in `load'
        1: from /home/quangphu/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
SyntaxError ((irb):33: no .<digit> floating literal anymore; put 0 before dot)
...rnel.raise _; rescue _.class; .8
...                              ^
(irb):33: syntax error, unexpected '.'
...rnel.raise _; rescue _.class; .8
...                              ^

4. Arithmetic in Ruby

Cũng như các ngôn ngữ lập trình khác thì Ruby cũng sử dụng các toán tử cơ bản như (+, -, &, /) để tính toán. Mình sẽ giới thiệu qua một vài phép tính đáng chú ý liên quan đến kiểu dữ liệu float, còn với nhau phép tính như 2 số kiểu intege thì đơn giản là nó sẽ trả về kiểu integer thôi.

Tất cả những phép tính sau sẽ đề trả về kiểu Float

float + numeric
float - numeric
float * numeric
float / numeric
float % numeric
float ** numeric
float -@

Ví dụ

a = 2.1
b = 2
   
# Addition 
c = a + b     
                    
puts "addition #{c}"
  
# Subtraction 
d = a - b     
  
puts "subtraction #{d}"
  
# Multiplication 
e = a * b    
  
puts "multiplication #{e}"
  
# Division 
f = a / b    
  
puts "division #{f}"
  
# Modulo 
g = a % b    
  
puts "modulo  #{g}"
  
# Exponent 
h = a ** b   
  
puts "exponent #{h}"
  
# Unary minus 
i= -a        
  
puts "unary minus #{i}"

Kết quả

addition 4.1
subtraction 0.1
multiplication 4.2
division 1.05
modulo  0.1
exponent 4.41
unary minus -2.1

Có một vài kiểu phép tính đặc biệt khác khi sử dụng phép chia với số 0

5/0
=> ZeroDivisionError (divided by 0)

5.1/0
=> Infinity

0.0 / 0.0
=> NaN

Trong Ruby sử dụng ký tự ** để làm toán tử mũ

Ví dụ: 3**2 tương ứng với 3^2

Đối với những toán tử mũ có giá trị quá lớn nó sẽ trả về kết quả là Infinity

9999999999999999999999999**99999999999999999999999
(irb):44: warning: in a**b, b may be too big
=> Infinity

6. Float Imprecision

Class Float mô tả giá trị không chính xác.

0.2 + 0.1 == 0.3 

Các bạn thử đoán xem kết quả trên trả về True hay False, nhìn sơ qua chắc hẳn ai cũng đoán là True thế nhưng kết quả lại là False.

Vì nếu bạn mở terminal ra kiểm tra giá trị của 0.2 + 0.1

0.2 + 0.1
=> 0.30000000000000004

Như chúng ta đã thấy thì kết quả của phép tính này sẽ trả về kiểu dữ liệu là BigDecimal – số thực với độ chính xác cao. Không giống như trong PHP chả hạn thì trong Ruby lại trả về 1 giá trị chính xác nhất có thể.

Trong PHP kết quả đơn giản sẽ chỉ là

0.2 + 0.1
=> 0.3

Để giải quyết vấn đề này, vì kiểu dữ liệu trả về là BigDecimal, nên chúng ta sẽ sử dụng luôn kiểu dữ liệu là BigDecimal để so sánh với độ chính xác cao. Vì BigDecimal không được tích hợp sẵn trong Ruby nên chúng ta phải require thư viện này vào

require 'bigdecimal'

BigDecimal("0.2") - BigDecimal("0.1") == 0.3 
=> true

7. Giới thiệu vài phương thức cơ bản

Để đổi kiểu String về dạng Integer với to_i

Integer("123")      # => 123
"123".to_i         # => 123
"123-hello".to_i   # => 123
"hello".to_i      # => 0

Làm tròn kiểu dữ liệu float với method round

4.89.round        # => 5
4.25.round        # => 4

Lấy độ chính xác của kiểu dữ liệu float bằng cách thêm tham số vào bên trong method round

3.141526.round(1) # => 3.1
3.141526.round(2) # => 3.14
3.141526.round(4) # => 3.1415

Kiểm tra số chẵn lẻ sử dụng even? odd?

4.even?      # => true
5.even?      # => false
4.odd?       # => false
5.odd?       # => true

Trên là cách sử dụng kiểu dữ liệu về số (number) trong ngôn ngữ Ruby, Chúc bạn học tốt, và hẹn gặp lại ở bài tiếp theo nhé.

Bài viết liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *