Bài toán được đặt ra như sau:
Code Examples
12. What does the following code output and why?
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts(“> 6”) : puts(“<= 6”);
}
-> This question tests whether you understand the integer promotion rules in C- an area that i find is very poorly understood by many developers.
Anyway, the answer is that this outputs "> 6".
The reason for this is that expression involving signed unsigned types have all operands promoted to unsigned types. Thus -20 becomes a very large positive integer and the expression evaluates to greater than 6 (caused -20 is converted from signed integer to unsigned integer).
This is a very important point in embedded systems where unsigned data types should be used frequently.
IF YOU GET THIS ONE WRONG, THEN YOU ARE PERILOUSLY CLOSE TO NOT BEING HIRED.
hahaha =)). xem thêm về thứ tự ưu tiên chuyển đổi bên dưới.
/*------------------------------------------------------------------------------------------------------
vậy Integer Promotion là gì?
.Numeric promotion
Bất cứ khi nào một giá trị từ một kiểu được chuyển đến giá trị của kiểu tương tự nhưng rộng hơn, nó được gọi là numeric promotion (hay là widening , nó thường xuyên dành cho kiểu int). Cho ví dụ, kiểu int có thể chuyển đến kiểu rộng hơn là long, float chuyển đến double.
long l(64); // mở rộng số nguyên 64 trong long
double d(0.12f); // "thăng cấp" float 0.12 trong kiểu double
Trong thuật ngữ "numeric promotion" chuyển một vài loại hình promotion,cũng có hai kiểu chuyển đổi khác cần lưu ý :
+ Intergral promotion liên quan đến chuyển đổi kiểu đổi của integer đến kiểu có phạm vi hẹp hơn int (ví dụ như bool, char, usigned char, signed char, usigned short , signed short) đến kiểu int (nếu có thể) hoặc kiểu unsigned int.
+Float point promotion liên quan đến chuyển đổi từ kiểu float sang double.
Hai loại trên đều được sử dụng trong các trườn hợp cụ thể đặc biệt để chuyển một kiểu dữ liệu nhờ nhơn đến int/ usigned int hay double, bởi vì thực hiện trên kiểu dữ liệu đó có hiệu suất nhất.
Một thứ quan trọng cần nhớ về promotions là chúng luôn an toán và không có dữ liệu nào bị mất.
.Phỏng đoán một biểu thức
Khi tính toán một biểu thức với các kiểu khác nhau, compiler tách từng biểu thức ra làm biểu thức con. Các toán tử toán học yêu cầu toán hạng của nó cùng kiểu. Nếu các toán hạng không cùng kiểu, compiler sẽ thực hiện chuyển đổi ngầm để chuyển một toán hạng. Để làm được điều này, nó phải tuân thủ các luật lệ sau:
+ NẾu toán hạng là kiểu nguyên, nó trải qua sự chuyển đổi "integral promotion" như đã nói ở trên.
+ Nếu toán hạng vẫn không phù hợp, compiler tìm toán hạng ưu tiên nhất (trong các toán hạng có trong biểu thức đó) và chuyển nó sang để phù hợp.
Toán hạng được ưu tiên như sau :
+ long double (highest)
+ double
+float
+ unsigned long long
+ long long
+unsigned long
+ long
+ usigned int
+ int (lowest)
/*-----------------------------------------------------------------------------------------*/
Hệ thống cấp bậc này có thể dẫn tới một vài vấn đề thú vị. Ví dụ, xem code :
std::cout << 5u - 10; // 5u có nghĩa là 5 như kiểu unsigned intteger
Bạn có lẽ mong rằng biểu thức 5u - 10 được tính là -5 vì 5 - 10 = -5 . Nhưng thực tế kết quả là
4294967291
std::cout << 5u - 10; // 5u có nghĩa là 5 như kiểu unsigned intteger
Bạn có lẽ mong rằng biểu thức 5u - 10 được tính là -5 vì 5 - 10 = -5 . Nhưng thực tế kết quả là
4294967291
Trong trường hợp này, signed integer (10) được "nâng cấp" lên thành unsigned int( vì nó có thự tự ưu tiên cao hơn), và biểu thức được tính với unsigned integer. Kết quả overflow và chúng ta nhận kết quả ko như mong đợi
Đây là một trong rất nhiều lý do để tránh việc sử dụng unsigned int.
Cảm ơn các bạn đã dành thời gian để xem .
Đây là một trong rất nhiều lý do để tránh việc sử dụng unsigned int.
Cảm ơn các bạn đã dành thời gian để xem .
Source:
http://theironns.blogspot.com/2015/12/chuyen-oi-kieu-trong-lap-trinh-type.html
0 comments :
Post a Comment