Lập trình cơ bản với Java (phần 3)
Giới thiệu
Trong bài viết này, ta sẽ khám phá kiểu dữ liệu số và các toán tử số học trong Java. Kiểu dữ liệu số là cơ sở cho việc biểu diễn và thao tác với các giá trị số nguyên và số thực. Các toán tử số học cho phép thực hiện các phép toán cơ bản như cộng, trừ, nhân và chia trên các kiểu dữ liệu số.
Bài viết cũng trình bày về các toán tử gán mở rộng, một tập hợp các toán tử tiện lợi để thực hiện các phép toán và gán giá trị trong một bước duy nhất. Sử dụng đúng kiểu dữ liệu và toán tử gán có thể giúp tối ưu hóa mã nguồn và cải thiện hiệu suất chương trình.
Kiểu dữ liệu số và các toán tử
Kiểu dữ liệu số
Trong Java, Numeric Types (Kiểu số học) được sử dụng để biểu diễn các loại giá trị số học, bao gồm số nguyên và số thực. Dưới đây là chi tiết về các numeric types trong Java:
-
Kiểu số nguyên (Integer Types):
- byte: Kiểu dữ liệu này chiếm 1 byte bộ nhớ. Phạm vi giá trị là từ -128 đến 127.
- short: Kiểu dữ liệu short chiếm 2 byte bộ nhớ. Phạm vi giá trị của short nằm trong khoảng từ -32,768 đến 32,767.
- int: Đây là kiểu số nguyên phổ biến trong Java, chiếm 4 byte bộ nhớ. Phạm vi giá trị của int rơi vào khoảng từ -2,147,483,648 đến 2,147,483,647.
- long: Long sử dụng 8 byte bộ nhớ, cho phép biểu diễn các số nguyên rất lớn. Phạm vi giá trị của long nằm trong khoảng từ -9,223,372,036,854,775,808 đến 9,223,372,036,854,775,807.
-
Kiểu số thực (Floating-Point Types):
- float: Float được sử dụng để biểu diễn số thực kiểu dấu chấm động với độ chính xác tương đối. Float chiếm 4 byte bộ nhớ. Nó có khoảng độ chính xác từ 6-9 chữ số thập phân.
- double: Double là kiểu số thực phổ biến, chiếm 8 byte bộ nhớ. Nó có độ chính xác cao hơn so với float, thường được sử dụng cho tính toán khoa học và kỹ thuật. Độ chính xác của double nằm trong khoảng từ 15-17 chữ số thập phân.
-
Kiểu số thực đặc biệt (Special Floating-Point Types):
- float và double có thể biểu diễn giá trị vô cực (Infinity) và NaN (Not-a-Number) để xử lý các tình huống đặc biệt như chia cho 0.
-
Kiểu số thập phân (Decimal Types):
- Java hỗ trợ kiểu số thập phân bằng thư viện
java.math.BigDecimal
vàjava.math.BigInteger
. Chúng được sử dụng cho tính toán chính xác với số thập phân và số nguyên lớn.
- Java hỗ trợ kiểu số thập phân bằng thư viện
-
Kiểu số nguyên không dấu (Unsigned Integer Types):
- Java không hỗ trợ kiểu số nguyên không dấu như nhiều ngôn ngữ khác. Thay vào đó, người lập trình phải sử dụng kiểu dữ liệu phù hợp với kiểu số nguyên và tự xử lý các giá trị không dấu.
Lưu ý rằng việc chọn kiểu số học phụ thuộc vào ngữ cảnh và yêu cầu cụ thể của bài toán. Nếu bạn cần tính toán chính xác số thập phân hoặc số nguyên lớn, bạn có thể sử dụng BigDecimal
hoặc BigInteger
. Nếu bạn cần biểu diễn số nguyên bình thường, bạn có thể sử dụng byte
, short
, int
, hoặc long
. Đối với số thực, double
thường là lựa chọn mặc định, nhưng bạn có thể cân nhắc sử dụng float
nếu độ chính xác không quá quan trọng và muốn tiết kiệm bộ nhớ.
Đọc dữ liệu kiểu số từ bàn phím
Trong Java, để đọc dữ liệu kiểu số từ bàn phím, bạn có thể sử dụng lớp Scanner
trong gói java.util
. Dưới đây là một ví dụ về cách đọc dữ liệu kiểu số từ bàn phím cho nhiều kiểu dữ liệu số khác nhau.
import java.util.Scanner;
public class ReadNumbers {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Đọc một số nguyên
System.out.print("Nhập một số nguyên: ");
int intValue = scanner.nextInt();
System.out.println("Số nguyên bạn vừa nhập là: " + intValue);
// Đọc một số thực (float)
System.out.print("Nhập một số thực (float): ");
float floatValue = scanner.nextFloat();
System.out.println("Số thực bạn vừa nhập là: " + floatValue);
// Đọc một số thực (double)
System.out.print("Nhập một số thực (double): ");
double doubleValue = scanner.nextDouble();
System.out.println("Số thực bạn vừa nhập là: " + doubleValue);
// Đọc một số nguyên lớn (long)
System.out.print("Nhập một số nguyên lớn (long): ");
long longValue = scanner.nextLong();
System.out.println("Số nguyên lớn bạn vừa nhập là: " + longValue);
// Đọc một số nguyên không dấu (unsigned int)
System.out.print("Nhập một số nguyên không dấu: ");
long unsignedIntValue = scanner.nextLong(); // Đọc dưới dạng long
System.out.println("Số nguyên không dấu bạn vừa nhập là: " + unsignedIntValue);
// Đọc một số thực với độ chính xác cao (BigDecimal)
System.out.print("Nhập một số thực với độ chính xác cao: ");
String bigDecimalValueString = scanner.next();
// Chuyển đổi chuỗi thành kiểu BigDecimal
java.math.BigDecimal bigDecimalValue = new java.math.BigDecimal(bigDecimalValueString);
System.out.println("Số thực bạn vừa nhập là: " + bigDecimalValue);
}
}
Lưu ý rằng bạn cần sử dụng kiểu dữ liệu tương ứng để lưu giá trị bạn đã đọc từ bàn phím. Điều này đảm bảo tính chính xác và tránh lỗi trong quá trình đọc và sử dụng dữ liệu.
Toán tử số học
Toán tử số học (numeric operators) trong Java là các toán tử được sử dụng để thực hiện các phép toán số học trên các biến số học. Dưới đây là chi tiết về các toán tử số học trong Java:
-
Toán tử Cộng (+): Toán tử này thực hiện phép cộng hai giá trị số học. Ví dụ:
int a = 5; int b = 3; int sum = a + b; // sum bây giờ có giá trị là 8
-
Toán tử Trừ (-): Toán tử này thực hiện phép trừ hai giá trị số học. Ví dụ:
int x = 10; int y = 7; int difference = x - y; // difference bây giờ có giá trị là 3
-
Toán tử Nhân (*): Toán tử này thực hiện phép nhân hai giá trị số học. Ví dụ:
int m = 4; int n = 6; int product = m * n; // product bây giờ có giá trị là 24
-
Toán tử Chia (/): Toán tử này thực hiện phép chia hai giá trị số học. Lưu ý rằng nó trả về một giá trị số thực (float hoặc double) nếu bất kỳ một trong hai giá trị đang tham gia phép chia là số thực. Ví dụ:
int p = 12; int q = 3; int result = p / q; // result bây giờ có giá trị là 4
-
Toán tử Chia Lấy Phần Dư (%): Toán tử này thực hiện phép chia hai giá trị số học và trả về phần dư sau phép chia. Ví dụ:
int dividend = 10; int divisor = 3; int remainder = dividend % divisor; // remainder bây giờ có giá trị là 1
Phép toán số mũ
Trong Java, phép tính mũ (exponentiation) không có một toán tử riêng như trong một số ngôn ngữ khác. Thay vào đó, ta sử dụng hàm Math.pow()
hoặc phép tính mũ với số nguyên (integer exponentiation) để tính toán mũ của một số. Dưới đây là cách bạn có thể thực hiện phép tính mũ trong Java:
-
Sử dụng
Math.pow()
:Hàm
Math.pow(a, b)
được sử dụng để tính giá trịa
mũb
. Cả hai tham sốa
vàb
đều là kiểu số thực (double
). Hàm này trả về một số thực.double base = 2.0; double exponent = 3.0; double result = Math.pow(base, exponent); // result sẽ có giá trị 2^3 = 8.0
-
Sử dụng phép tính mũ với số nguyên (integer exponentiation):
Nếu chỉ muốn tính giá trị số mũ của một số nguyên, ta có thể sử dụng một vòng lặp (ta sẽ làm quen chi tiết trong các bài viết sau) hoặc một cách đệ quy để thực hiện phép tính mũ. Dưới đây là một ví dụ sử dụng vòng lặp:
int base = 2; int exponent = 3; int result = 1; for (int i = 0; i < exponent; i++) { result *= base; } // result sẽ có giá trị 2^3 = 8
Ví dụ trên tính 2 mũ 3 bằng cách nhân 2 với chính nó 3 lần.
Lưu ý rằng nếu cần tính mũ với số nguyên lớn hoặc kiểu số thực với độ chính xác cao, bạn nên sử dụng BigDecimal
hoặc BigInteger
từ package java.math
để tránh lỗi tràn số hoặc mất độ chính xác.
Toán tử gán mở rộng
Toán tử gán mở rộng (tiếng anh là Augmented Assignment Operators) là một tập hợp các toán tử trong lập trình mà thường được sử dụng để thực hiện các phép toán và gán giá trị trong một bước duy nhất. Chúng được thiết kế để rút ngắn và làm cho mã nguồn trở nên ngắn gọn hơn, đồng thời giúp tối ưu hóa quá trình thực hiện các phép toán cơ bản.
Các Augmented Assignment Operators bao gồm:
+= (Addition Assignment Operator): Sử dụng để cộng giá trị của biến với một giá trị khác và gán lại cho biến đó. Ví dụ: x += 5; tương đương với x = x + 5;.
-= (Subtraction Assignment Operator): Sử dụng để trừ giá trị của biến đi một giá trị khác và gán lại cho biến đó. Ví dụ: x -= 3; tương đương với x = x - 3;.
*= (Multiplication Assignment Operator): Sử dụng để nhân giá trị của biến với một giá trị khác và gán lại cho biến đó. Ví dụ: x *= 2; tương đương với x = x * 2;.
/= (Division Assignment Operator): Sử dụng để chia giá trị của biến cho một giá trị khác và gán lại cho biến đó. Ví dụ: x /= 4; tương đương với x = x / 4;.
%= (Modulus Assignment Operator): Sử dụng để lấy phần dư sau khi chia giá trị của biến cho một giá trị khác và gán lại cho biến đó. Ví dụ: x %= 7; tương đương với x = x % 7;.
&= (Bitwise AND Assignment Operator): Sử dụng để thực hiện phép AND bitwise giữa giá trị của biến và một giá trị khác, sau đó gán kết quả lại cho biến. Ví dụ: x &= 3; tương đương với x = x & 3;.
|= (Bitwise OR Assignment Operator): Sử dụng để thực hiện phép OR bitwise giữa giá trị của biến và một giá trị khác, sau đó gán kết quả lại cho biến. Ví dụ: x |= 6; tương đương với x = x | 6;.
^= (Bitwise XOR Assignment Operator): Sử dụng để thực hiện phép XOR bitwise giữa giá trị của biến và một giá trị khác, sau đó gán kết quả lại cho biến. Ví dụ: x ^= 1; tương đương với x = x ^ 1;.
<<= (Left Shift Assignment Operator): Sử dụng để thực hiện phép dịch trái (left shift) bit giá trị của biến bởi một số lượng bit cụ thể và gán kết quả lại cho biến. Ví dụ: x <<= 2; tương đương với x = x << 2;.
>>= (Right Shift Assignment Operator): Sử dụng để thực hiện phép dịch phải (right shift) bit giá trị của biến bởi một số lượng bit cụ thể và gán kết quả lại cho biến. Ví dụ: x >>= 3; tương đương với x = x >> 3;.
>>>= (Unsigned Right Shift Assignment Operator): Sử dụng để thực hiện phép dịch phải không dấu (unsigned right shift) bit giá trị của biến bởi một số lượng bit cụ thể và gán kết quả lại cho biến. Ví dụ: x >>>= 2; tương đương với x = x >>> 2;.
Các Augmented Assignment Operators giúp làm cho mã nguồn ngắn gọn và dễ đọc hơn, đồng thời cải thiện hiệu suất của chương trình bằng cách giảm số lượng phép toán lặp lại và gán giá trị.
Lời kết
Trong bài viết này, chúng ta đã khám phá kiểu dữ liệu số và các toán tử số học trong Java. Việc lựa chọn đúng kiểu số cho mỗi tình huống là rất quan trọng để đảm bảo tính chính xác và hiệu suất của chương trình. Đối với tính toán chính xác số thập phân hoặc số nguyên lớn, ta sử dụng BigDecimal hoặc BigInteger. Đối với số thực thông thường, bạn có nhiều kiểu dữ liệu như byte, short, int, long, float, và double để lựa chọn. Bài viết cũng giới thiệu các toán tử số học và toán tử gán mở rộng, giúp tối ưu hóa mã nguồn và thực hiện các phép toán một cách tiện lợi. Hy vọng rằng bài viết này đã giúp bạn nắm vững kiến thức về số học và phép toán trong Java, hỗ trợ hữu ích trong công việc lập trình.
©️ Tác giả: Trần Quang Hiệp từ Viblo
All rights reserved