Trong các ngôn ngữ lập trình, muốn thực hiện thao tác tính toán thì luôn cần phải có toán tử. Bài viết chia sẻ về những lỗi trả về kết quả không như ý muốn, và đây là một vấn đề quan trọng nhưng lại ít được để ý tới.
Toán tử /
Những điều lưu ý khi sử dụng toán tử /
Trong quá trình biên dịch, nếu phát hiện một lệnh gán giá trị khác loại cho một biến, trình biên dịch sẽ tự động chuyển kiểu, gọi là cơ chế chuyển kiểu ngầm định, tránh nhầm lẫn giữa phép chia các số nguyên trong toán học và phép chia các số nguyên trong lập trình, dẫn đến kết quả lập trình không được như mong muốn.
double d = 13; // tự động chuyển giá trị của d thành 13.0 int n = 16.95; // tự động chuyển giá trị của n thành 16
Khi cả 2 toán tử thuộc dạng nguyên (int
- short
- long
) thì nó là phép chia lấy phần nguyên.
Ví dụ:
- 8/7 được 1
- 14/6 được 2
//số nguyên int a = 8; short b = 7; printf("%d", a / b); // kết quả = 1 long c = 14; long d = 6; printf("%d", c / d); // kết quả = 2
Khi 1 trong 2 toán tử thuộc dạng số thực (float
- double
) thì nó sẽ là phép chia thập phân bình thường.
float a = 5; float b = 4; printf("%f", a / b);
Những sai lầm khi sử dụng toán tử /
Khi sử dụng toán tử /
, nguyên nhân kết quả không như mong muốn đó là do chưa áp dụng được những lưu ý trước khi sử dụng toán tử.
Xét ví dụ sau cho ra kết quả sai:
// vd1: float a = 3/4; printf("%f", a); //a = 0 // vd2: int b = 2; a = 1 / b; printf("%f", a); // a = 0
Như vậy ở 2 lần int
ra kết quả a = 0
, đều là kết quả không như mong muốn.
- Ví dụ 1: trong tư duy toán học, khi nhìn thấy
a = 3/4
đều tự nghĩa = 0.75
và mặc định trong đầufloat a = 0.75
, nhưng đối với trình biên dịch, khi hai số nguyên chia nhau thì kết quả lấy phần nguyên do đófloat a = (int)3/(int)4
và ra kết quảfloat a = 0
. - Ví dụ 2: tương tự như ở trên, trình biên dịch sẽ hiểu theo nghĩa
a = (int)1/(int)b
và ra kết quảfloat a = 0
.
Giải pháp chuyển kiểu
Là việc chuyển một dữ liệu sang kiểu dữ liệu khác theo ý muốn, cú pháp chuyển kiểu như sau:
(<kiểu dữ liệu>)<dữ liệu cần chuyển>
Sửa code trên để ra kết quả đúng:
float a = ((float)3) / 4; printf("%f", a); int b = 2; a = 1 / (float)b; printf("%f", a);
Lưu ý: ở đoạn code trên, chuyển kiểu ((float)3)
nhưng 4
thì không cần phải chuyển, vì các hạng tử không cùng kiểu, sẽ xảy ra chuyển kiểu ngầm định, kiểu nhỏ hơn sẽ chuyển sang kiểu lớn hơn, do đó 4
sẽ tự động chuyển thành ((float)4)
, dãy cấp độ như sau:
- long double // (highest).
- double.
- float.
- unsigned long int.
- long int.
- unsigned int.
- int // (lowest).
Toán tử == trong C++
Xét ví dụ sau:
// vd1 float a = 2.512; if (a == 2.512) printf("true"); else printf("false"); // vd2 int a = 2, b = 2, c = 2; if (a == b == c) printf("true"); else printf("false"); // vd3 int a = 5; int b = 4; if (a = b) printf("true"); else printf("false");
- Ví dụ 1: kết quả trả về
false
, việc so sánh số có kiểu dữ liệu là float với 1 hằng số, và kiểu dữ liệu của hằng số này làdouble
, do đó dẫn đến sai số. Do đó để tránh ra kết quả sai, sửa lại đoạn code thành:if(a == 2.512f)
. - Ví dụ 2: kết quả trả về
false
, hiểu như sau: đầu tiên so sánh từ trái qua phải, do đóa == b
⇒true
, tiếp theotrue == c
⇒false
vậy kết quả làfalse
. Sửa lại đoạn codeif( a == b && b == c)
hoặcif( a == b && a == c)
. - Ví dụ 3: kết quả trả về
true
, đây là lỗi thường gặp do gõ code, giữa=
(phép gán) và==
(phép so sánh) là 2 thế giới khác nhau, tuy nhiên vẫn thường lầm tưởng về điều đó.
Toán tử == trong PHP
Tránh những lỗi khi sử dụng toán tử trong php vì các kiểu dữ liệu trong php tự động chuyển các biến sang các kiểu thích hợp để thực hiện phép tính. Như ví dụ đoạn code dưới đây, cho ra kết quả true
vì php đã chuyển cùng kiểu dữ liệu rồi so sánh.
$a = 5; $b = '5'; if($a == $b) { echo "true"; } else { echo "false"; }
Sau đây là bảng trả về những kết quả đúng nhưng thường dễ bị hiểu lầm.
Ví dụ | Kết quả | Nguyên nhân |
---|---|---|
NULL == '' | true | NULL được chuyển về chuỗi rỗng |
NULL == FALSE | true | NULL được chuyển về FALSE |
NULL == 0 | true | NULL sẽ bằng với bất kỳ giá trị nào tương ứng với FALSE như 0, "0", 0.00 |
FALSE = '0' | true | Chuỗi rỗng và 0 sẽ bị ép kiểu về FALSE. |
TRUE = 'false' | true | Bất kỳ chuỗi nào khác rỗng đều bị ép kiểu về TRUE. |
3.5 == '3.5 km' | true | Chuỗi sẽ được chuyển về số và so sánh |
0 == '' | true | Chuỗi rỗng bị ép về 0. |
0 == 'STDIO' | true | Chuỗi không chứa số bị ép về 0. |
Toán tử ===
Đoạn code dưới đây, khi in kết quả true = 1
và chữ yes
.
// VÍ DỤ 1 <?php echo true; // kết quả = 1 if(true == 1) echo "yes"; else echo "no"; ?>
Tuy nhiên trong php còn có toán tử ===
, khi in kết quả sẽ ra chữ no
tại đoạn code thứ 2.
// VÍ DỤ 2 <?php if(true === 1) echo "yes"; else echo "no"; ?>
Như vậy sự khác biệt giữa ==
(so sánh) và ===
(so sánh đồng nhất), toán tử đồng nhất hoàn toàn không sử dụng ép kiểu, do đó nếu hai giá trị khác kiểu được so sánh (true
kiểu boolean
và 1
kiểu integer
) thì kết quả luôn trả về chữ no
như ví dụ 2.