[Game Maker Adventure] Chương 004: Data Type: string, int, float, double
Tóm tắt chương trước
Bạn bị kéo vào không gian trong Cổ Thư, buộc phải trả lời những câu đố kì lạ để có thể trở về.
Kiến thức chương này
- string là một chuỗi các kí tự nằm trong hai dấu ngoặc kép.
- string còn có thể nối với nhau thông qua dấu cộng (+).
- Khi thực hiện phép chia giữa hai số int, hãy cẩn thận kết quả của chúng.
- Gán dữ liệu cho biến float phải có thêm hậu tố (suffix) f. VD: float number = 204.31f;
- Mỗi một kiểu dữ liệu đều có giới hạn ghi nhớ của nó.
Cốt truyện
Trở lại thế giới thực, bạn không khỏi cảm thấy kinh ngạc.
Thế giới này quả thực rất kì diệu.
Nhưng liệu nó còn kì diệu tới đâu nữa?
Bạn muốn tìm ra câu trả lời.
Bạn phải tìm ra câu trả lời!
Trong lúc cao hứng, bạn tiếp tục lật tiếp sang chương mới…
Data Type là gì?
Ở chương trước, chúng ta đã được biết về Variables hay còn gọi là biến.
Để sử dụng biến, ta cần declare (khai báo) độ lớn của vùng nhớ và tên của vùng nhớ đó (variable name). Cả hai thứ này đều do người dùng qui định.
Thay vì tên vùng nhớ là được đặt theo sở thích mỗi người, độ lớn của vùng nhớ bắt buộc phải đặt theo qui ước.
Vùng nhớ trong máy tính rất phức tạp nên người ta sử dụng luôn tên của các kiểu dữ liệu (data type) để qui định vùng nhớ của chúng.
Mỗi kiểu dữ liệu khác nhau sẽ được tối ưu để làm một việc khác nhau. Một số kiểu dữ liệu thường gặp (và sẽ đề cập tới trong series) là:
- string: chuyên văn bản (hội thoại nhân vật, chữ trên …).
- int: chuyên số nguyên (đếm số kẻ địch, đạn còn lại, highscore…).
- float: chuyên số thực (tính sát thương, tính góc,…).
- double: giống float nhưng xịn hơn, đòi nhiều bộ nhớ hơn.
- bool: đúng hoặc sai (đã chạm đất chưa? HP đã về 0 chưa?…).
- enum: chuyên về lựa chọn (số mùa trong năm, trạng thái nhân vật,…).
Kiểu dữ liệu: string
string là một chuỗi các kí tự, thường được sử dụng để lưu trữ dữ liệu dạng văn bản.
string có rất nhiều ứng dụng: chữ trong bóng thoại, chữ trong thông báo, chữ trên UI, tin nhắn… miễn là chữ thì nó là string!
Trong code, string là một chuỗi các kí tự nằm trong hai dấu ngoặc kép (kể cả số). VD:
string message1 = "day la string";
string message2 = "9"; //day cung la string (van ban) khong phai so
Để khai báo (declare) string, ta chỉ cần thêm từ khoá string vào trước tên biến.
Để gán dữ liệu cho string, ta phải sử dụng dấu ngoặc kép.
Ngoài ra, string còn có thể nối với nhau thông qua dấu cộng (+) hay còn gọi là string concatenation. VD:
string message1 = "day la noi ";
string message2 = "string";
Console.WriteLine(message1 + message2); //print: day la noi string
Một thí dụ khác về nối string:
string message1 = "day la " + "noi ";
string message2 = "string";
Console.WriteLine(message1 + message2); //print: day la noi string
Hay như thế này cũng được:
string message1 = "day la ";
string message2 = "string";
Console.WriteLine(message1 + "noi " + message2); //print: day la noi string
Kiểu dữ liệu: int
int là viết tắt của integer – tức số nguyên. Số nguyên tức là số… không phải phân số, không phải số thập phân. VD: 502, -2, 0,…
Số nguyên thường được sử dụng trong tính highscore, đếm số mèo, đếm số mạng còn lại, tổng số lượng kẻ địch…
Để khai báo int, ta thêm từ khoá int vào trước tên biến. Còn gán dữ liệu thì phải đưa số nguyên vào (không được đưa số thực như 21.25, 999.1).
int myNumber = 9;
Int có thể biểu diễn từ số -2,147,483,648 tới 2,147,483,647. Kiểu int chiếm 4 bytes bộ nhớ mỗi lần khai báo, nghĩa là, nếu bạn khai báo 2 biến int thì máy tính sẽ dành ra 8 bytes để nhớ.
Một số trường hợp gây lỗi thường gặp:
- int myNumber = 9.5; – 9.5 không phải số nguyên, int không thể lưu được.
- int myNumber = “9”; – “9” là string, không phải số.
- int myNumber = 2147483648; vượt quá bộ nhớ cho phép của số int.
Với int, ta có thể cộng (+), trừ (-), nhân (*) và chia (/) chúng. VD:
int number1 = 2;
int number2 = 4;
Console.WriteLine(number1 + number2); //kqua: 6
Console.WriteLine(number1 * number2); //kqua: 8
Console.WriteLine(number1 - number2); //kqua: -2
Console.WriteLine(number1 / number2); //kqua: 0
Phép chia là một trường hợp đặc biệt. Ở trong ví dụ trên, ta thấy 2/4 = 0. Lẽ ra kết quả phải là 0.5 phải không? Vậy tại sao kết quả trong máy lại ghi bằng 0?
Nguyên nhân của việc này là do các operator (+, -, *, /…). Bản chất của chúng là tất cả đầu vào phải cùng kiểu dữ liệu, tất cả đầu ra cũng phải có cùng kiểu dữ liệu đó.
Trong trường hợp này, do đầu vào là 2 số nguyên nên kết quả sẽ là số nguyên.
2/4 = 0.5, máy tính sẽ bỏ .5, ta được kết quả là 0. Tương tự 9/10 = 0.9 thì cũng bị cắt bỏ .9 thành 0.
Vì thế người ta thường sử dụng các kiểu dữ liệu số thực như float hoặc double để thực hiện phép chia.
Kiểu dữ liệu: float
Với int, ta chỉ có thể biểu diễn chính xác đến hàng đơn vị. Vậy, nếu ta muốn biểu diễn các con số chính xác hơn nữa như gây 298.22 sát thương, độ cao 1.08m, kĩ năng còn 9.29s… thì ta sẽ phải làm gì?
Rất đơn giản, đó là sử dụng số thực – mà ở đây là kiểu float (trong số thực có rất nhiều kiểu khác nhau, float chỉ là một trong số đó).
Để khai báo float, ta thêm từ khoá float vào trước tên biến. Gán dữ liệu cho biến float phải có thêm hậu tố (suffix) f. VD:
float number = 2.6f;
Khi không có hậu tố f, Visual Studio sẽ ngay lập tức báo lỗi:
Bạn có thể có thể cộng (+), trừ (-), nhân (*), chia (/) với float như toán bình thường.
Kiểu float có thể biểu diễn chính xác khoảng 6-7 số sau dấu chấm (VD: 0.000001).
Float có thể biểu diễn từ số ±1.0 × 10^-45 tới ±3.4 × 10^38. Float cũng cần 4 bytes để lưu trữ (giống int) nhưng float nhớ được những số lớn hơn rất-rất-rất nhiều.
Ủa, vừa chiếm cùng dung lượng bộ nhớ, vừa thể hiện được nhiều số hơn như vậy chúng ta có thể không-bao-giờ đụng đến int nữa?
Ờm… không hẳn.
Về bản chất, int và float khác nhau ở cách mà máy tính xử lí chúng.
- Kiểu float là do máy dùng phép nhân một số với bội của 10. Số float càng lớn càng thiếu độ chính xác. Float chỉ có thể biểu diễn 6-7 số sau dấu chấm nên việc lưu 2000000000f và 2000000001f là giống nhau, chúng đều là 2.000000 x 10^9. Hãy tưởng tượng một nhân vật có máu 2000000000 (2 tỉ) kiểu float, nhân vật đó lao vào chiến trường, chịu hàng tỉ lần 1 sát thương và nhân vật ấy vẫn không giảm một xíu máu nào. Tất cả các dòng code đều không hề sai và bạn tìm đỏ mắt không ra bug…
- Ngược lại, kiểu int được nhớ trực tiếp theo hệ binary vì thế số int rất chính xác. Hãy xem thí dụ bên dưới để hiểu thêm nhé.
float number3 = 2000000000f;
float number4 = 2000000000f + 1;
Console.WriteLine(number3 - number4);
//kqua = 0
int number = 2000000000;
int number2 = 2000000000 + 1;
Console.WriteLine(number - number2);
//kqua = -1
Với float, việc tăng thêm 1 vào một số đã lớn không có ý nghĩa.
Phần bonus: Ngoài ra, các bạn có thể xem thêm bài giới thiệu về bit và byte ở đây để xem kiểu int được ghi nhớ theo hệ binary như thế nào nhé.
Kiểu dữ liệu: double
Kiểu float số càng lớn càng thiếu chính xác, kiểu int thì chính xác nhưng không làm lớn được.
Để giải quyết cả hai điểm yếu đó hãy sử dụng kiểu double.
int number = 2000000000;
int number2 = 2000000000 + 1;
Console.WriteLine(number - number2);
//kqua = -1
double number3 = 2000000000;
double number4 = 2000000000 + 1;
Console.WriteLine(number3 - number4);
//kqua = -1
Ở thí dụ trên ta thấy dù cộng thêm 1 vào một số rất lớn thì double vẫn có khả năng làm đúng. Khác hẳn với float.
Về bản chất, double vận hành giống float nhưng double chuẩn hơn do nó chiếm nhiều dữ liệu hơn (8 bytes), với độ chính xác 15-16 số sau dấu phẩy.
Double có thể thể hiện những số từ ±5 × 10^-324 đến ±1.7 × 10^308 (ờm… bạn chẳng phải nhớ chúng làm gì đâu, số này quá lớn rồi.).
Trong một số trường hợp bạn cần số lớn (hoặc rất lớn) giống như các game clicker/idle, bạn nên sử dụng double hoặc để biểu diễn giá trị sát thương của người chơi.
Để gán dữ liệu cho kiểu double, bạn không cần thêm hậu tố. VD:
double number = 2059.1551;
Quest: Giấc mơ kì lạ
Sau khi đọc xong chương này bạn chợt thấy ngoài trời không còn sáng nữa.
Bạn phải nhanh chóng dựng trại.
Nhưng…
Bạn không biết cách dựng một cái trại đàng hoàng!
Chỉ còn cách chui vào một hốc cây nhỏ, bạn thở dài, cuộn mình và thiếp đi lúc nào không hay.
…
“)??(__@$- FireBallToTarget(enemy); @>?-25)(+)!*–“
“>>>>>>>>>>>>>>>>>>>>>>–!!!!!!!!!!!”
“?????! Không có hiệu quả rồi!! Nhanh n-!—@(^!)_:!”
“>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>___!!!!!!!!!!!!!!”
Một vùng đất chìm trong biển lửa.
Từng đàn quái vật cứ ngã xuống lại được hồi sinh, rồi chúng lại ngã xuống…
Chúng đang vây quanh một nhóm người xa lạ-!? Khoan! Một trong số họ là bạn!!
Trong lúc đang ngạc nhiên, “bạn” bỗng nhìn thẳng vào “bạn”: L9)@__><##3<>>!
Gì vậy? Bạn đang nói gì đó bạn không hiểu!!
…
Thế rồi, bạn bừng tỉnh…
Nhận thấy bạn đã thức dậy, cuốn sách ngay lập tức kéo bạn vào không gian của nó.
Quest ✦✧✧✧✧
Hãy chọn câu trả lời đúng trước khi qua chương sau nhé.
Chương Trước | Tổng quan | Chương Kế