Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Khóa học lập trình C++ căn bản

5.0 (19 đánh giá)
Tạo bởi Kteam Cập nhật lần cuối 5 năm trước 255.951 lượt xem 10 bình luận
Tác giả/Dịch giả: Kteam
Học nhanh

Danh sách bài học

01. Giới thiệu về C++ 02. Cài đặt môi trường phát triển (IDE) Visual studio 2015 03. Xây dựng chương trình C++ đầu tiên với Visual Studio 2015 04. Cấu trúc một chương trình C++ (Structure of a program) 05. Ghi chú trong C++ (Comments in C++) 06. Biến trong C++ (Variables in C++) 07. Số tự nhiên và Số chấm động trong C++ (Integer, Floating point) 08. Kiểu ký tự trong C++ (Character) 09. Kiểu luận lý và cơ bản về Câu điều kiện If (Boolean and If statements) 10. Nhập, Xuất và Định dạng dữ liệu trong C++ (Input and Output) 11. Hằng số trong C++ (Constants) 12. Toán tử số học, toán tử tăng giảm, toán tử gán số học trong C++ (Operators) 13. Toán tử quan hệ, logic, bitwise, misc và độ ưu tiên toán tử trong C++ 14. Cơ bản về chuỗi ký tự trong C++ (An introduction to std::string) 15. Biến cục bộ trong C++ (Local variables in C++) 16. Biến toàn cục trong C++ (Global variables in C++) 17. Biến tĩnh trong C++ (Static variables in C++) 18. Ép kiểu ngầm định trong C++ (Implicit type conversion in C++) 19. Ép kiểu tường minh trong C++ (Explicit type conversion in C++) 20. Cơ bản về Hàm và Giá trị trả về (Basic of functions and return values) 21. Truyền Giá Trị cho Hàm (Passing Arguments by Value) 22. Truyền Tham Chiếu cho Hàm (Passing Arguments by Reference) 23. Tiền khai báo và Định nghĩa Hàm (Forward declarations and Definitions of Functions) 24. Giới thiệu về cấu trúc điều khiển (Control flow introduction) 25. Câu điều kiện If và Toán tử điều kiện (If statements and Conditional operator) 26. Câu điều kiện Switch trong C++ (Switch statements) 27. Câu lệnh Goto trong C++ (Goto statements) 28. Vòng lặp While trong C++ (While statements) 29. Vòng lặp Do while trong C++ (Do while statements) 30. Vòng lặp For trong C++ (For statements) 31. Từ khóa Break and continue trong C++ 32. Phát sinh số ngẫu nhiên trong C++ (Random number generation) 33. Mảng 1 chiều trong C++ (Arrays) 34. Các thao tác trên Mảng một chiều 35. Mảng 2 chiều trong C++ (Two-dimensional arrays) 36. Các thao tác trên Mảng 2 chiều 37. Mảng ký tự trong C++ (C-style strings) 38. Các thao tác trên Mảng ký tự (C-style strings) 39. Từ khóa auto trong C++11.(The auto keyword) 40. Vòng lặp for each trong C++11 (For each loops) 41. Lớp dựng sẵn Array trong C++11 42. Con trỏ cơ bản trong C++ 43. Con trỏ NULL trong C++ (NULL pointers) 44. Con trỏ và mảng trong C++ (Pointers and arrays) 45. Các phép toán trên Con trỏ và Chỉ mục mảng trong C++ (Pointers and arrays) 46. Cấp phát động trong C++ (Dynamic memory allocation). 47. Cấp phát mảng động (Dynamically allocating arrays) 48. Con trỏ & Hằng trong C++ 49. Biến tham chiếu trong C++.(Reference variables) 50. Con trỏ void (Void pointers) 51. Con trỏ trỏ đến con trỏ (Pointers to pointers) 52. Cơ bản về lớp Vector 53. Truyền địa chỉ cho hàm (Passing arguments by address) 54. Hàm trả về giá trị, tham chiếu và địa chỉ trong C++(value, reference, and address) 55. Hàm nội tuyến trong C++ (Inline functions) 56. Nạp chồng hàm trong C++ (Function overloading) 57. Hàm có đối số mặc định trong C++ (Default arguments) 58. Con trỏ hàm trong C++ (Function pointers) 59. Đệ quy trong C++ (Recursion) 60. Khuôn mẫu hàm trong C++ (Function templates)

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Dẫn nhập

Ở bài học trước, bạn đã nắm được BIẾN TRONG C++ (Variables), và đã biết nguyên lý hoạt động và một số kinh nghiệm về biến trong C++. Và bài học trước chỉ đề cập cơ bản về biến của một số nguyên.

Trong C++ vẫn còn rất nhiều kiểu dữ liệu khác, bạn sẽ được học 2 loại kiểu dữ liệu mới trong bài học hôm nay: Số nguyên và Số chấm động trong C++ (Integer, Floating point)


Nội dung:

Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về phần:

Trong bài này, ta sẽ cùng tìm hiểu các vấn đề:

  • Tổng quan về kiểu dữ liệu cơ bản trong C++
  • Kiểu số nguyên (Integer)
  • Kiểu số chấm động (Floating point)

Tổng quan về kiểu dữ liệu cơ bản trong C++

Ở bài học trước Biến trong C++ (Variables), bạn đã biết biến (variable) là tên của một vùng trong bộ nhớ RAM, được sử dụng để lưu trữ thông tin. Bạn có thể gán thông tin cho một biến, và có thể lấy thông tin đó ra để sử dụng. Có rất nhiều loại thông tin (Ví dụ: thông tin dưới dạng số nguyên, số thực, ký tự, …), và trong C++, các biến cũng có thể lưu những loại thông tin khác nhau thông qua các kiểu dữ liệu khác nhau.

Kích thước của biến phụ thuộc vào kiểu dữ liệu của biến đó và quyết định số lượng thông tin mà biến đó lưu trữ. Khi bạn khai báo một biến, một vùng trong bộ nhớ sẽ dành cho biến đó. Ngày nay, việc khai báo biến với kích thước vài byte không là vấn đề gì, so với độ lớn của bộ nhớ máy tính. Nhưng nếu chương trình của bạn có số lượng biến lên tới hàng triệu, thì việc phải sử dụng biến với kích thước sao cho phù hợp là điều rất quan trọng.

Bảng bên dưới sẽ liệt kê những kiểu dữ liệu cơ bản trong C++. Kích thước kiểu dữ liệu tương ứng bên dưới chỉ là kích thước nhỏ nhất có thể của kiểu dữ liệu đó. Trong thực tế, kích thước này phụ thuộc vào từng compiler và kiến trúc máy tính.

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)


Để xác định kích thước của một kiểu dữ liệu trên một máy tính cụ thể, C++ cung cấp cho bạn toán tử sizeof. Toán tử sizeof là toán tử một ngôi, nhận vào một kiểu dữ liệu hoặc một biến, và trả về kích thước (byte) của của kiểu dữ liệu hoặc biến đó.

Ví dụ:

Chương trình bên trên khi thực thi trên Window 7 x64 (Visual studio 2015) sẽ cho ra kết quả:

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Một điều thú vị là toán tử sizeof là một trong 3 toán tử không phải là ký hiệu trong C++, 2 toán tử còn lại là new và delete sẽ được giới thiệu trong bài CẤP PHÁT ĐỘNG (Dynamic memory allocation).


Kiểu số nguyên (Integer)

Số nguyên là các số nguyên dương (1, 2, 3, …), các số đối (-1, -2, -3, …) và số 0. C++ có 5 loại số nguyên cơ bản để sử dụng:

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Chú ý: Char là một kiểu dữ liệu đặc biệt, nó vừa là kiểu số nguyên, cũng vừa là kiểu ký tự.

Chi tiết về tính chất ký tự của char sẽ được nói trong phần Character. Ở mục này, bạn tạm thời coi nó là một kiểu số nguyên bình thường.

Sự khác nhau giữa các kiểu số nguyên trên nằm ở kích thức. Kiểu có kích thước lớn sẽ lưu được những số nguyên lớn. Vùng giá trị của một kiểu số nguyên được xác định trên 2 yếu tố: kích thước và dấu của nó.

Số nguyên có dấu là những số nguyên dương (1, 2, 3, …), các số đối (-1, -2, -3, …) và số 0. Có 2 cách để khai báo một biến số nguyên có dấu:

Số nguyên không dấu là những số nguyên dương (1, 2, 3, …) và số 0. Đôi khi chương trình của bạn có những biến không cần lưu trữ các số âm (Ví dụ: chiều cao, cân nặng, độ dài, chỉ số danh sách, …). Để khai báo số nguyên không dấu, bạn sử dụng từ khóa unsigned. Ví dụ:

Lưu ý: Một số nguyên không dấu không thể lưu trữ các số âm, nhưng nó có thể lưu trữ số dương lớn hơn gấp 2 lần số nguyên có dấu.

Bên dưới là bảng miền giá trị số nguyên

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)


Số chấm động (Floating point numbers) 

Trong C++, kiểu số chấm động đại diện cho số thực (Ví dụ: 69.9696, 3.14159, 0.00001 …), dùng để lưu trữ những số rất lớn hoặc rất nhỏ. Cấu trúc lưu trữ bên trong của số thực được thiết kế theo chuẩn số chấm động (floating-point) của IEEE.

Số chấm động không có từ khóa unsigned. Có 3 kiểu số chấm động khác nhau trong C++: float, double, long double.

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Chú ý: Một số môi trường lập trình đồng nhất kiểu long double với kiểu double nên kiểu này ít được sử dụng trong lập trình ứng dụng.

Cách để định nghĩa một biến số chấm động:

// Definitions of floating point numbers
float fVarName;
double dVarName2;
long double ldVarName3;

Chú ý:

Khi bạn sử dụng một hằng số dưới dạng một số chấm động, quy ước số đó phải có ít nhất 1 chữ số thập phân, điều này giúp phân biệt số chấm động và số nguyên.

Ví dụ:

Chú ý: Mặc định một hằng số thực sẽ là kiểu double. Để có một số thực kiểu float, bạn cần thêm hậu tố ‘f’.


Ký hiệu khoa học (Scientific notation)

Ký hiệu khoa học là cách xử lý những số rất lớn hoặc rất nhỏ. Ví dụ: chu kỳ xoay mặt trăng của Mộc Tinh là 152853.5047 s. Khi đó, bạn có thể viết bằng ký hiệu khoa học là 1.528535047 × 105 s. Hay một số khá quen thuộc với bạn như khối lượng của một electron là 9.1093822 x 10-31. Bên dưới là một số ví dụ khác:

24327 = 2.4327 x 104

7354 = 7.354 x 103

0,0078 = 7.8 x 103

0,00069 = 6.9 x 10-4

Chú ý: Số mũ sẽ là dương nếu dấu thập phân chuyển sang phải, là âm nếu dấu thập phân chuyển sang trái.

Trong C++, bạn có thể sử dụng ký hiệu khoa học để gán giá trị cho biến số chấm động. Dùng ký hiệu ‘e’ hoặc ‘E’ để thay cho 10.

Ví dụ:


Độ chính xác của số chấm động (Precision)

Số chấm động sẽ bao gồm những số hữu hạn và vô hạn. Đối với số vô hạn, nghĩa là phần thập phân sẽ có chiều dài vô hạn (Ví dụ: 1/6 = 0.1666666666666…, PI = 3.141592653589793…), nhưng bộ nhớ máy tính và kích thước kiểu dữ liệu thì hữu hạn. Nên biến số chấm động chỉ lưu được một độ chính xác nhất định, và phần số còn lại phía sau sẽ bị mất.

Trong C++, khi xuất một số chấm động, std::cout mặc định số có 6 chữ số. Những số ngoài phạm vi sẽ bị cắt bỏ và làm tròn lên 1 đơn vị nếu số bị cắt sau nó lớn hơn 5, hoặc số đó có thể được chuyển sang ký hiệu khoa học trong vài trường hợp tùy vào từng compiler. Ví dụ:

Chương trình bên trên khi thực thi trên Window 7 x64 (Visual studio 2015) sẽ cho ra kết quả:

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Mặc dù khi xuất một số chấm động, std::cout mặc định độ chính xác có 6 chữ số, nhưng bạn vẫn có thể thay đổi được độ chính xác này bằng cách sử dụng hàm std::setprecision() thuộc thư viện <iomanip>.

Kết quả thu được:

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Trong chương trình trên, ta đã thay đổi độ chính xác lên đến 20 chữ số thay vì là 6 chữ số như mặc định. Nhưng dù 2 biến floatdouble đều đã hiện đủ 20 chữ số, thì độ chính xác của nó vẫn không đến 20 chữ số.

Thông thường số chấm động kiểu float có độ chính xác đơn (single-precision), chính xác đến 7 chữ số. Double có độ chính xác kép (double-precision), chính xác đến 16 chữ số. Đó là lý do tại sao chương trình trên lại có những số rác sau khoảng chính xác.

Độ chính xác của số chấm động không chỉ ảnh hưởng trên phần thập phân, mà nó có thể ảnh hưởng trên phần nguyên của những số có quá nhiều chữ số.

Ví dụ:

Kết quả thu được:

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point) 

Vì kiểu float có độ chính xác 7 chữ số, nên chương trình đã xuất ra 123.456.792, số này lớn hơn giá trị biến ban đầu rất nhiều. Do đó, bạn nên cẩn thận khi sử dụng kiểu float để lưu trữ những số cần một độ chính xác cao.

Chú ý: Bạn nên sử dụng kiểu double khi cần lưu trữ một số chấm động, hạn chế sử dụng float vì kiểu float có độ chính xác thấp sẽ dẫn tới số không chính xác.


Lỗi làm tròn số chấm động (Rounding errors)

Trong máy tính, số chấm động được lưu dưới hệ nhị phân.

Ví dụ: ta có phân số 1/10, = 0.1 trong hệ thập phân = 0.000110011(0011)… trong hệ nhị phân (lặp vô hạn). Ta thấy số 0.1 chuyển sang hệ nhị phân sẽ lặp vô hạn, nhưng độ chính xác của số chấm động là hữu hạn. Dẫn đến việc nó không thể được biểu diễn một cách chính xác như một giá trị nhị phân hữu hạn. Xét ví dụ:

Kết quả chương trình:

Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Trong chương trình trên, ta có một biến double d{0.1}. Khi output với độ chính xác mặc định std::setprecision(6), ta nhận được chính xác 0.1. Nhưng khi output với std::setprecision(20), kết quả lại lớn hơn 0.1.

Kết quả cho thấy khi gán số 0.1 cho một biến số chấm động, biến đó sẽ không hoàn toàn bằng 0.1. Đó gọi là lỗi làm tròn số chấm động.

Xét tiếp ví dụ:

Kết quả chương trình:

 Số tự nhiên và Số chấm động trong C++ (Integer, Floating point)

Trong chương trình trên, trong toán học thì 2 biến d1 = d2, nhưng trong lập trình biến d1 > d2 vì lỗi làm tròn số dấu chấm động.

Tương tự, bạn hãy thử với trường hợp 0.1 + 0.7 = 0.8 ?

Chú ý: Không bao giờ so sánh hai giá trị dấu chấm động bằng nhau hay không. Hầu như luôn luôn có sự khác biệt nhỏ giữa hai số chấm động. Cách phổ biến để so sánh 2 số chấm động là tính khoảng cách giữa 2 số đó, nếu khoảng cách đó là rất nhỏ thì ta cho là bằng nhau. Giá trị dùng để so sánh với khoảng cách đó thường được gọi là epsilon. Điều này sẽ được giải thích rõ hơn trong bài Câu điều kiện If trong C++ (If statements).


Kết luận

Qua bài học này, bạn đã nắm được kiểu Số nguyên và Số chấm động trong C++ (Integer, Floating point), và đã biết được những kinh nghiệm cũng như những lỗi thường gặp khi sử dụng nó.

Trong bài học tiếp theo, mình sẽ giới thiệu cho các bạn một kiểu dữ liệu khá quan trọng trong lập trình: KIỂU KÝ TỰ TRONG C++ (Data types).

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.


Tải xuống

Tài liệu

Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Số tự nhiên và Số chấm động trong C++ (Integer, Floating point) dưới dạng file PDF trong link bên dưới.

Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com

Đừng quên likeshare để ủng hộ Kteam và tác giả nhé!


Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.

Tác giả/Dịch giả

Khóa học

Khóa học lập trình C++ căn bản

Hiện nay, C++ đã là cái tên rất quen thuộc trong ngành lập trình. Mặc dù C++ là ngôn ngữ lập trình đã ra đời khá lâu, nhưng không phải ai cũng có cơ hội để tìm hiểu về nó.

Vì vậy, Kteam đã xây dựng lên khóa học LẬP TRÌNH C++ CĂN BẢN để cung cấp một lượng kiến thức về ngôn ngữ C++ nói riêng, và các khái niệm khác trong lập trình nói chung.

Nội dung khóa học sẽ được phân tách một cách chi tiết, nhằm giúp các bạn dễ hiểu và thực hành được ngay. Serial dành cho những bạn chưa có bất kỳ kiến thức gì về lập trình, hoặc những bạn mất căn bản muốn lấy lại kiến thức nền tảng lập trình, cụ thể là C++.

Đánh giá

5.0
19 đánh giá
Đánh giá
5
19
4
3
2
1
Ngà Trần đã đánh giá 8 tháng trước

win1702 đã đánh giá 9 tháng trước

TurtleVietNam đã đánh giá khoảng 1 năm trước

phanđat đã đánh giá 3 năm trước

rayolardo104 đã đánh giá 3 năm trước

Bình luận

Để bình luận, bạn cần đăng nhập bằng tài khoản Howkteam.

Đăng nhập
mioit.17 đã bình luận 10 tháng trước

010624

HackerTryTyping đã bình luận 5 năm trước

Em xin góp ý ạ. Thay vì học 1000+2000=3000, ta có thể học phép dễ hơn 1+2=3. Thay vì setprecision(20),sao anh không thử set khoảng (1;5], vừa dễ nhìn, vừa dễ tiếp thu. Những thứ còn lại cứ để khả năng suy diễn, quy nạp của mỗi người.

phamduylong1742000 đã bình luận 5 năm trước

ad ơi trong chương trình xem byte của từng kiểu dữ liệu. ad cho e hỏi mỗi cái /t là ntn ? có chỗ /t có chỗ /t/t là sao ??

 

trinh10101010 đã bình luận 7 năm trước

Xin chào, em xin phép copy phần nội dung bài học phía trên ạ!

1611931 đã bình luận 8 năm trước
ad cho em hỏi là muốn số chấm động mình xuất ra ko tự động dùng kí hiệu khoa học thì phải làm sao ạ?
Không có video.