2008-08-29 13 views
5

Một số mã mà viên đạn lên bộ phận để chứng minh (C-cú pháp):Làm thế nào để chia hai số 64 bit trong nhân Linux?

#define SINT64 long long int 
#define SINT32 long int 

SINT64 divRound(SINT64 dividend, SINT64 divisor) 
{ 
    SINT32 quotient1 = dividend/divisor; 

    SINT32 modResult = dividend % divisor; 
    SINT32 multResult = modResult * 2; 
    SINT32 quotient2 = multResult/divisor; 

    SINT64 result = quotient1 + quotient2; 

    return (result); 
} 

Bây giờ, nếu này là người sử dụng không gian chúng ta có lẽ sẽ không còn nhận thấy rằng trình biên dịch của chúng tôi là tạo mã cho những nhà khai thác (ví dụ divdi3() để chia). Rất có thể chúng tôi liên kết với 'libgcc' mà không hề biết. Vấn đề là không gian hạt nhân là khác nhau (ví dụ: không có libgcc). Phải làm gì?

thu thập thông tin của Google trong một thời gian, thông báo rằng khá nhiều tất cả mọi người đề cập đến biến unsigned:

#define UINT64 long long int 
#define UINT32 long int 

UINT64 divRound(UINT64 dividend, UINT64 divisor) 
{ 
    UINT32 quotient1 = dividend/divisor; 

    UINT32 modResult = dividend % divisor; 
    UINT32 multResult = modResult * 2; 
    UINT32 quotient2 = multResult/divisor; 

    UINT64 result = quotient1 + quotient2; 

    return (result); 
} 

tôi biết làm thế nào để sửa lỗi này một: Override udivdi3()umoddi3() với _do_div () _ từ asm/div64.h. Đã xong rồi? Sai rồi. Đã ký không giống như unsigned, sdivdi3() _ không chỉ đơn giản gọi udivdi3(), chúng là các hàm riêng biệt vì một lý do.

Bạn đã giải quyết được sự cố này chưa? Bạn có biết một thư viện sẽ giúp tôi làm điều này? Tôi thực sự bị mắc kẹt vì vậy bất cứ điều gì bạn có thể thấy ở đây mà tôi chỉ cần không ngay bây giờ sẽ thực sự hữu ích.

Cảm ơn, Chad

Trả lời

0

ldiv?

Chỉnh sửa: đọc lại tiêu đề, vì vậy bạn có thể muốn bỏ qua điều này. Hoặc không, tùy thuộc vào nó có phiên bản không phải thư viện thích hợp hay không.

4

Đây là giải pháp thực sự ngây thơ của tôi. Số dặm của bạn có thể thay đổi.

Giữ bit dấu, là sign(dividend)^sign(divisor). (Hoặc * hoặc /, nếu bạn đang lưu trữ dấu của bạn dưới dạng 1 và -1, trái ngược với sai và đúng. Về cơ bản, âm nếu một trong hai là âm, dương nếu không có hoặc cả hai đều âm.)

Sau đó, , gọi hàm phân chia không dấu trên các giá trị tuyệt đối của cả hai. Sau đó, tack các dấu hiệu trở lại vào kết quả.

P.S. Đó thực sự là cách __divdi3 được triển khai trong libgcc2.c (từ GCC 4.2.3, phiên bản được cài đặt trên hệ thống Ubuntu của tôi). Tôi chỉ cần kiểm tra. :-)

0

Tôi không nghĩ (ít nhất là không thể tìm thấy một cách để làm) Chris' answer làm việc trong trường hợp này vì do_div() thực sự thay đổi cổ tức tại chỗ. Nhận giá trị tuyệt đối ngụ ý một biến tạm thời có giá trị sẽ thay đổi theo cách tôi yêu cầu nhưng không thể được chuyển ra khỏi số ghi đè __divdi3().

Tôi không thấy một con đường xung quanh các tham số theo giá trị chữ ký của __divdi3() vào thời điểm này ngoại trừ việc bắt chước các kỹ thuật được sử dụng bởi do_div().

Có vẻ như tôi đang cúi xuống phía sau ở đây và chỉ cần đưa ra thuật toán để thực hiện bộ phận 64 bit/32 bit mà tôi thực sự cần. Mặc dù vậy, sự phức tạp thêm ở đây là tôi có một bó mã số bằng toán tử '/' và cần phải đi qua mã đó và thay thế mọi '/' bằng các lời gọi hàm của tôi.

Tôi đang tuyệt vọng, đủ để làm điều đó.

Thanks cho bất kỳ theo dõi, Chad