2013-04-06 43 views
5

Tôi đang làm việc trên một dự án nhúng, trong đó tôi phải ghi một giá trị hết thời gian vào hai thanh ghi byte của một số vi chip.Phân tách số nguyên thành hai byte

Các time-out được định nghĩa là:

timeout = REG_a * (REG_b +1) 

Tôi muốn chương trình này đăng ký sử dụng một số nguyên trong khoảng từ 256 đến phép nói 60000. Tôi đang tìm kiếm một thuật toán mà, cho một timeout- giá trị, tính REG_a và REG_b.

Nếu một giải pháp chính xác là không thể, tôi muốn nhận được giá trị thời gian chờ lớn hơn có thể tiếp theo.

Tôi đã làm gì cho đến nay:

giải pháp hiện tại của tôi tính toán:

temp = integer_square_root (timeout) +1; 
    REG_a = temp; 
    REG_b = temp-1; 

Điều này dẫn đến giá trị mà làm việc tốt trong thực tế. Tuy nhiên tôi muốn xem các bạn có thể đưa ra một giải pháp tối ưu hơn không.

Ồ, và tôi bị hạn chế về bộ nhớ, vì vậy các bảng lớn không được đề cập đến. Ngoài ra thời gian chạy là quan trọng, vì vậy tôi không thể chỉ đơn giản là brute-lực lượng giải pháp.

+0

Bạn có muốn giảm thiểu chênh lệch giữa 'timeout' và giá trị được tính không? Đó có phải là mục đích của bài tập này không? Nếu không những gì bạn có vẻ tốt. –

+0

Một phiên bản tối ưu là giảm thiểu một đăng ký và tối đa hóa một đăng ký khác. Có thể có vấn đề với giao diện đăng ký này, nơi bạn không muốn thay đổi cả hai thanh ghi đột ngột. Vì bạn không thể làm cả hai bộ nhớ ghi cùng một lúc, có thể có vấn đề nếu sổ đăng ký được viết ** trong khi ** bộ hẹn giờ đang chạy. Bằng cách giảm thiểu một đăng ký, bạn có thể để nó giống nhau khi đi đến một thời gian chờ nhỏ hơn vì mức tối thiểu cho độ chi tiết thời gian tốt hơn. –

Trả lời

2

Bạn có thể sử dụng mã được sử dụng trong câu trả lời Algorithm to find the factors of a given Number.. Shortest Method? để tìm yếu tố hết giờ.

n = timeout 
initial_n = n 
num_factors = 1; 
for (i = 2; i * i <= initial_n; ++i) // for each number i up until the square root of the given number 
{ 
    power = 0; // suppose the power i appears at is 0 
    while (n % i == 0) // while we can divide n by i 
    { 
     n = n/i // divide it, thus ensuring we'll only check prime factors 
     ++power // increase the power i appears at 
    } 
    num_factors = num_factors * (power + 1) // apply the formula 
} 

if (n > 1) // will happen for example for 14 = 2 * 7 
{ 
    num_factors = num_factors * 2 // n is prime, and its power can only be 1, so multiply the number of factors by 2 
} 
REG_A = num_factor 

Yếu tố đầu tiên sẽ là REG_A của bạn, vì vậy bạn cần tìm một giá trị khác nhân với thời gian chờ.

for (i=2; i*num_factors != timeout;i++); 
REG_B = i-1 
1

Vấn đề thú vị, Nils!

Giả sử bạn bắt đầu bằng cách sửa một trong các giá trị, hãy nói Reg_a, sau đó tính toán Reg_b theo phân chia bằng cách làm tròn: Reg_b = ((timeout + Reg_a-1)/Reg_a) -1.

Sau đó, bạn biết bạn thân thiết, nhưng gần gũi như thế nào? Vâng giới hạn trên về lỗi sẽ là Reg_a, phải không? Bởi vì lỗi là phần còn lại của bộ phận.

Nếu bạn thực hiện một trong các yếu tố càng nhỏ càng tốt, sau đó tính toán yếu tố khác, bạn sẽ làm cho giới hạn trên đó bị lỗi càng nhỏ càng tốt.

Mặt khác, bằng cách làm cho hai yếu tố gần căn bậc hai, bạn đang làm cho số chia càng lớn càng tốt và do đó làm cho lỗi càng lớn càng tốt!

Vì vậy:

Đầu tiên, giá trị tối thiểu cho Reg_a là bao nhiêu? (timeout + 255)/256;

Sau đó tính Reg_b như trên.

Đây sẽ không phải là sự kết hợp tối thiểu tuyệt đối trong mọi trường hợp, nhưng nó phải tốt hơn so với sử dụng căn bậc hai và nhanh hơn.

Các vấn đề liên quan