Lỗi lập trình trong C.

HP_No1

New member
GÂY DỰNG
Mấy Bác ơi, thành như khi lập trình C trong PPC chạy thông qua PocketDos v1.11.0 bị lỗi kiểu dữ liệu Float (chắc sai về dấu chấm động) hay sao đó?.

Em xài Ipaq 5550, dùng cùng 1 souce chương trình chạy thử trên Laptop và PPC thì thấy bị lỗi như như vậy?Cụ thể khi chia, 8 cho 4 thì cho kết quả trên Laptop là 2.00000 còn trên PPC thì lại là 12.00000

Bác nào có kinh nghiệm sữa lỗi này giúp em với.
 
- Bác post nhầm box rồi
- bác cho xem cái code mới biết đường mà sửa
 
Một code đơn giản C trên PPC

Bác ơi, e, VD một code đơn giản Bác chạy thử dùm em trên PPC xem có bị như em kg nhe, em đã chạy thử trên PC thì cho kết quả lại đúng, trên PPC lại sai:( :

int a, b;
float thuong;
printf ("Nhap 1 so a nguyen duong= "); scanf ("%d",&a);
printf ("Nhap 1 so b nguyen duong= "); scanf ("%d",&b);
thuong = (float) a/b;
printf ("Thuong hai so la %f\n,thuong);

Khi nhập a= 8 , b= 4....thì trên PC cho kết quả là 2.000000, còn trên PPC lại là 12.000000...pó tay luôn.
Đây là 1 VD nhỏ thôi,,mà sao PPC lại sai như vậy buồn quá,Bác nào tìm lỗi giúp em với.

Cám ơn các Bác quan tâm.
 
Có một điều phải nói rằng, bạn viết câu hỏi như vậy là bạn đang lên đây than thở chứ chẳng phải lên để hỏi gì cà vì không ai có hứng thú trả lời bạn cả. Bạn phải đưa nguyên source code của bạn (bao gồm cả project file) để người ta biên dịch kiểm tra thì mới chỉ lỗi cho bạn được. Tất nhiên, bạn không muốn đưa toàn bộ source code và mọi người cũng chẳng hơi đâu đọc cái mớ bòng bong đó cả, bạn hãy tạo một project mới, trong đó chứa phần code tối thiểu mà bạn nghi là sai, và file .exe sau biên dịch chắc chắn bị sai.

Một kinh nghiệm cho thấy, thay vì chờ đợi câu hỏi thì hãy tự mình kiểm lỗi còn nhanh hơn, chỉ hỏi người khác khi không thể tìm lỗi được nữa.

Còn cái ví dụ bạn đưa ra, tôi thề với bạn rằng chẳng ai trả lời cho bạn cả. Và tôi tự hỏi liệu có console prompt trên WinCe để tôi test đoạn mã đó không.
 
Bạn nói như vậy là không đúng, tui mới bắt đầu học ngôn ngữ C, tui không viết cả một chương trình lớn như bạn nghĩ, tui chỉ muốn làm 1 phép tính "chia" trên PPC, thì phát hiện ra giữa PC và PPC lại cho hai kết quả khác nhau. Tui đã thử hết mọi cách, có thế kg phải lỗi tại CPU của PPC mà là lỗi tại phần mềm PocketDos v1.11.0....

Ý tui đưa ra vấn đề này, là tui muốn tìm hiểu lỗi sai như vậy là do đâu, tui khẳng định các dòng lịnh do tui viết ra trên C là hoàn toàn kg sai, vì câu lệnh rất đơn giản, và tui đã biên dich ra .exe chạy trên PC và PPC luôn. Thì PC va PPC lại cho kết quả khác nhau.

Tui chỉ mong muốn tìm hiểu, sự khác nhau giữa PPC và PC là như thế nào thôi??? Bác nào có lòng tốt, và thích tìm hiểu, thì giúp tui biên dịch cái dòng lịnh dưới đây ra .exe rồi chạy thử trên PPC xem có bị lỗi giống tui kg?

#include <math.h>
main ();
{
int a, b;
float thuong;
printf ("Nhap 1 so a nguyen duong= "); scanf ("%d",&a);
printf ("Nhap 1 so b nguyen duong= "); scanf ("%d",&b);
thuong = (float) a/b;
printf ("Thuong hai so la %f\n,thuong);
getch ();
return 0;
}

Nhập a= 8, b=4...thì PPC cho kết quả là 12.000000.

Cảm ơn các Bác quan tâm.
 
Ok, tôi chẳng bao giờ dùng shell trên PDA cả, nên cũng không dùng cái PocketDos, nên không thể test đoạn mã trên được. Nhưng tôi có thể giúp bạn biết rõ sự khác biệt giữa PC và PPC. Loại bỏ sự khác nhau về GUI, thì PC và Pocket PC có hai điểm khác biệt chính sau.

1. CPU sử dụng trên Pocket PC hiện tại theo kiến trúc ARM, đây là kiến trúc tập lệnh rút gọn (RISC - Reduced instruction set computer), bạn có thể tự tham khảo thêm về RISC. Có điều cần nói để bạn biết là ARM không có tính toán float, một phép chia float có thể dùng đến hàng ngàn lệnh (được cài đặt thủ công và release dưới dạng lib đi kèm với compiler); không có phép chia. Vì vậy muốn chương trình chạy nhanh, bạn cần đặc biệt chú ý những lệnh không tồn tại (không được hỗ trợ ở mức CPU) trong CPU.

2. Memory Management. Bộ nhớ heap trên CE được quản lý theo từng page, mỗi page 1kb, nhỏ hơn rất nhiều so với PC. Đây cũng là một điểm rất quan trọng, cần đặc biệt chú ý nếu bạn lập trình game đồ họa đòi hỏi tốc độc cao. Trên PC bạn có thể ép kiểu bộ nhớ từ BYTE* thành ULONG* (4 bytes cho mỗi đơn vị LONG), để tăng tốc copy bộ nhớ (mỗi lần gán giá trị là 4 bytes thay vì 1 byte), trên Pocket PC vì mỗi page có 1kb và được quản lý rất chặt, nên dùng kiểu đó chắc chắn sẽ phát sinh lỗi. Chỉ có thể sử dụng phương pháp trên nếu bạn dùng Virtual Allocation. Đây là một kinh nghiệm xương máu của tôi.

Đó là điểm khác biệt về kiến trúc xử lý, không chỉ trên Pocket PC mà còn trên Windows Smartphone, Symbian, Palm và Motorola Linux PDA (MobiLinux). Tôi đã đụng tay chân đến rất nhiều hệ điều hành dành cho PDA, tôi chỉ thấy hai điểm khác biệt trên là cực kỳ quan trọng, có thể gây những lỗi mà nhưng coder ít kinh nghiệm có thể mất hàng tuần vẫn không tìm ra lỗi. Còn những khác biệt như File System, GUI, Input là không đáng kể.

Còn về đoạn mã của bạn, bạn thử như sau xem có được không.
Mã:
#include <math.h>
main ();
{
int a, b;

/* input */
printf ("Nhap 1 so a nguyen duong= "); scanf ("%d",&a);
printf ("Nhap 1 so b nguyen duong= "); scanf ("%d",&b);

/* display in int */
printf ("a = %d\nb = %d\nc = %d", a, b, a / b);

/* display in float */
printf ("a = %f\nb = %f\nc = %f\nd = %f", (float)a, (float)b, (float)(a / b),((float) a) / ((float) b));

getch ();
return 0;
}
Đoạn
Mã:
printf ("a = %d\nb = %d\nc = %d", a, b, a / b);
dùng để kiểm tra giá trị nhập có đúng không. Nếu vẫn bị lỗi thì bạn có thể tin rằng thư viện float có vấn đề.
 
Mình chưa thử test chương trình của HP_No1, nhưng xem code thì thấy rằng đã sai cú pháp khi ép kiểu. Code của khaplienhoa trả lời là chính xác rồi. Dù sao phải test thì mới biết chính xác, nhưng kinh nghiệm cho thấy thì chắc chắn code của khaplienhoa chạy đúng. :D
 
Mở rộng tầm nhìn.

Trời ơi...em bái phục bác quá.:p
Bây giờ em mới biết ARM kg hỗ trợ kiểu float, làm em hí hoáy làm cả ngày trời kg tìm được lỗi. Vậy từ nay, em kg còn làm bài tập C trên PPC được nữa rồi,,,hehe,,,:D
Kiến thức của Bác giúp ích cho em nhiều lắm đó, em nhớ hết những kinh nghiệm của Bác. Thành thật rất cám ơn Bác khaplienhoa.

Cái code bác cho em, em chạy trên PPC cũng ra kết quả sai luôn. Như vậy khẳng định là tại CPU ARM rồi.
 
Chạy code của bác khaplienhoa!!!

Em bê nguyên xi code của Bác khaclienhoa vào PPC và PC cho chạy thử rồi. Kết quả như sau:
include <math.h>
main ()
{
int a, b;
/* input */
printf ("Nhap 1 so a nguyen duong= "); scanf ("%d",&a);
printf ("Nhap 1 so b nguyen duong= "); scanf ("%d",&b);
/* display in int */
printf ("a = %d\nb = %d\nc = %d", a, b, a / b);
/* display in float */
printf ("a = %f\nb = %f\nc = %f\nd = %f", (float)a, (float)b, (float)(a/ b),((float) a) / ((float) b));
getch ();
return 0;
}
1.Nhâp lần 1, a= 9, b= 3
*Kết quả hiện trên PPC là a=9, b=3, c=3a=9.000000, b=3.000000, c= 3.000000, d= 12.000000

*Kết quả trên PC là a=9, b=3, c=3a=9.000000, b=3.000000, c=3.000000, d= 3.000000

2.Nhập lần 2, a=9, b=2
Kết quả hiện trên PPC là a=9, b=2, c=4a=9.000000, b=2.000000, c= 4.000000, d= 11.000000

Kết quả hiện trên PC là a=9, b=2, c=4a=9.000000, b=2.000000, c= 4.000000, d= 4.500000


Bác khaplienhoa ơi với kết quả trên Bác có nhận xét gì kg? và biện pháp khắc phục trên PPC, em tiếc quá, tiếc Bác khaplienhoa kg có PPC.
Cảm ơn các bác quan tâm.
 
Mã lệnh cơ bản của ARM không hỗ trợ floating-point, cho nên như bác khaplienhoa nói, việc tính toán +, -, *, / được thực hiện bằng thư viện hàm tính toán floating-point theo chuẩn IEEE. Cụ thể với PPC, thư viện các hàm này gồm __adds, __subs, __muls, __divs... nằm trong file coredll.dll. Mỗi hàm gồm khoảng vài trăm lệnh ARM.

Ở đoạn code bác HP_No1 vừa chạy ở trên, do được biên dịch mã lệnh và sử dụng thư viện của PocketDos, nên kết quả tính toán floating-point bị sai sót. Như vậy có thể kết luận theo hai khả năng:
- [1]. Nếu PocketDos tự thực hiện các công việc tính toán dâu phẩy động bằng thư viện của riêng mình mà không dùng tới thư viện của HĐH (coredll.dll), ta kết luận được là thư viện này bị sai sót.
- [2]. Nếu PocketDos sử dụng thư viện của HĐH, như vậy nguyên nhân la do trình biên dịch đã thực hiện sai.

To HP_No1: Với kết quả như trên, bác không nên dùng trình biên dịch của PocketDos làm gì nữa, mà nên sử dụng trình biên dịch của Microsoft cung cấp nằm trong bộ công cụ eMbedded Visual C++. Trình biên dịch này đã được kiểm nghiệm kĩ, thực hiện tính toán dấu phẩy động qua thư viện của HĐH.
 
Bạn nên sài theo cú pháp này nhé:
thuong = float(a)/b;
hoặc
thuong = float(a)/float(b);
(tôi chưa thử đâu :D )
Sao ko sài eVC hay .Net05???
 
Back
Top