30/09/2018, 16:48

Giải thích cách printf với %ld %d %f đối với kiểu long int, int, float?

#include <stdio.h>
#include <conio.h>
void main()
{
   long int li; int i; float f; clrscr();
   li = 0x123456; f = 123.456;
   i = (int) li;
   printf("
 li = %ld; i = %d",li,i);
   i = (int) f;
   printf("
 f = %f; i = %d",f,i);
   getch();
}

Kết quả :

li=1193046; i=13398
f=123.456001; i=123

Mình đã có kết quả nhưng chưa hiểu nó được tính bằng cách nào và công thức ra sao. Ai biết thì trả lời giúp. Cảm ơn !

Gió viết 18:48 ngày 30/09/2018
li=0b100100011010001010110
#khi cast li->i (int có kích thước 16 bit nên nó lấy 16 bit cuối)
i=0b0011010001010110 # =13398
# khi cast số thực sang số nguyên -> nó chỉ lấy phần nguyên thôi :)   
Nguyễn Minh Dũng viết 19:00 ngày 30/09/2018

Đây không phải là tính, mà chỉ là in ra thôi. Ta hiểu như sau

li = 0x123456

li có kiểu long int nhận vào là 0x123456 với tiền tố 0x thì C hiểu đây là số hệ 16. Thử lấy máy tính đổi hệ 16 0x123456 xem có ra giống kết quả chương trình này in ra không?

i=13398

Ta thấy i có kiểu int. Trong trường hợp này int chỉ có 4 bytes thôi. Trong khi số 0x123456 có tới 6 bytes. Thế nên C sẽ chỉ lấy 4 bytes thấp, tức 0x3456. Lấy máy tính bấm 0x3456 hệ 16 đổi sang hệ 10 ta được 13398

f = 123.456;

f là kiểu float, ta thấy giá trị nhập vào là 123.456, tuy nhiên giá trị in ra lại là 123.456001. Lý do bởi vì float là số thực, trong C số thực gọi là Single-precision floating-point. Ta có thể hiểu “sơ sơ” là số thực không phải là một con số chính xác. Khi sử dụng float thì C sẽ tự động “nâng cấp” float thành double. Double có độ chính xác gấp đôi float. Do việc chuyển đổi này sẽ phát sinh sai số, dẫn đến lòi ra số 1 ở cuối. Để giải quyết vấn đề này ta có hai giải pháp.

  • Khai báo f ở dạng double ngay từ đầu: double f;
  • Chỉ in ra 4 số lẻ ở phía sau (hoặc tổng phần chẵn và phần lẻ tầm 7 số thôi)
printf("\n f = %.4f; i = %d",f,i);

Trường hợp cuối:

i=123

Lý do là i được gán bằng f. Phần lẻ phía sau sẽ bị bỏ đi. i chỉ nhận phần nguyên.

Lê Chinh viết 18:49 ngày 30/09/2018

Ta thấy i có kiểu int. Trong trường hợp này int chỉ có 4 bytes thôi. Trong khi số 0x123456 có tới 6 bytes. Thế nên C sẽ chỉ lấy 4 bytes thấp, tức 0x3456. Lấy máy tính bấm 0x3456 hệ 16 đổi sang hệ 10 ta được 13398

Kiểu int chỉ có 2 byte chứ mấy anh @ltd. ?

Nguyễn Minh Dũng viết 18:53 ngày 30/09/2018

Ngày trước thì int là 2 Bytes, nhưng bây giờ thì int đã là 4 bytes trên hầu hết các thể loại máy rồi.

P/S: Em muốn quote bài thì em bôi đen đoạn muốn Quote và bấm Quote Reply.

Bài liên quan
0