Có một thay thế không nổi cho pow ()?


9

Tôi đã truy quét TÀI LIỆU THAM KHẢO trong trang web Arduino và tôi không thể tìm thấy một phi nổi tương đương với việc pow() tôi đã bỏ lỡ một điều gì đó lớn lao, nhưng đối với cuộc sống của tôi, tôi đã bối rối! Tôi đã tìm thấy pow()trong cột FUNCTION dưới tiêu đề Toán học (như tôi mong đợi), nhưng nó nói rằng cả hai tham số, [cơ sở] và [số mũ] đều là (float). Và chỉ có sáu mục khác dưới tiêu đề Toán học; không ai trong số họ dường như là một phiên bản số nguyên. Tất cả những gì tôi muốn làm là tạo ra sức mạnh của 2 bằng cách sử dụng số mũ từ 0 đến 10. Giống như 2 ^ 0 = 1 rồi 2 ^ 1 = 2 rồi 2 ^ 2 = 4 rồi 2 ^ 3 = 8 rồi 2 ^ 4 = 16 rồi 2 ^ 5 = 32 rồi 2 ^ 6 = 64 rồi 2 ^ 7 = 128 rồi 2 ^ 8 = 256 rồi 2 ^ 9 = 512 thì 2 ^ 10 là 1024

Là sử dụng phao là cách duy nhất tôi có thể làm điều này? Tôi bắt đầu cảm thấy như mình bất hòa với thực tế, và thực sự đã đếm được thuốc của mình, nhưng tôi đang ở đúng nơi tôi nên đến. Hãy để tôi xin lỗi trước vì sự giám sát quá lớn này mà tôi đã lãng phí thời gian của bạn, nhưng tôi đã xem qua tất cả 9 trang thẻ và đã thực hiện tìm kiếm mà tôi có thể nghĩ ra. Tôi sẽ thừa nhận rằng tôi đã không dành nhiều thời gian, nhưng tôi chắc chắn rằng điều này sẽ chỉ giống như một điều năm phút!


2
Đối với trường hợp chung của số nguyên pow (), hãy xem stackoverflow.com/questions/101439/ . Đối với quyền hạn của 2, chỉ cần sử dụng ca.
Peter Cordes

Câu trả lời:


8

Đối với trường hợp chung, câu trả lời của @dat_ha là chính xác, nhưng điều đáng chú ý là bạn muốn có một trường hợp rất đặc biệt ... quyền hạn của hai. Bởi vì máy tính sử dụng số học nhị phân, các hoạt động liên quan đến quyền hạn của hai thường có sẵn một số phím tắt.

Nhân một số với lũy thừa hai có thể được thực hiện bằng thao tác dịch chuyển trái ( <<), nghĩa đen sẽ dịch chuyển các chữ số của biểu diễn nhị phân của số (tức là các bit) sang trái. Trong cơ sở hai, việc dịch chuyển các bit một vị trí sang trái giống như nhân với 2, giống như trong cơ sở 10 chữ số dịch chuyển một vị trí bên trái giống như nhân với 10. Để giải thích đầy đủ về toán tử dịch chuyển trái trong C ++ , xem câu trả lời này trên Stack Overflow .

Điều quan trọng cần lưu ý là dịch chuyển trái có thể mất thông tin; bit bị dịch chuyển ra khỏi cuối bị mất. Vì bạn cần có sức mạnh từ 2 đến 10, nên bạn an toàn khi làm việc với các số nguyên đã ký, có giá trị tối đa 2^15-1trên Arduino Uno .

Với những cảnh báo này, đây là một hàm để tính toán sức mạnh của hai trong những ràng buộc này. Đây là mã rất nhanh vì thao tác dịch chuyển trái là hoạt động ở mức rất thấp và không có phép nhân nào thực sự được thực hiện.

int pow2(int p){
    return 1 << p;
}

Lỗi: Nó có thể lên tới 2 ^ 32 - 1 nếu bạn sử dụng unsigned long.
Đạt Hà

@DatHa cảm ơn, tôi dường như đã mất từ ​​"đã ký" trong khi chỉnh sửa. Đã sửa.
Jason Clark

1
Nó có thể đi qua 2 ^ 32 - 1 nếu bạn sử dụng triển khai số học số nguyên chính xác tùy ý
Dat Han Bag

Tôi muốn, đặc biệt để biết lý do tại sao kết quả của một chuyển đổi số nguyên trên kết quả của pow () KHÔNG hoạt động với quyền hạn của 2. Đối với tôi, pow (2,3) trả về 8,00, nhưng trong khi int (8,00) trả về 8 , int (pow (2,3)) trả về 7!
KDM

1

Nó hoạt động với int, double, longfloat. unsigned longunsigned intcũng nên làm việc. Bạn không cần phải sử dụng phao CHỈ.

Hy vọng nó sẽ giúp!


Lý do câu trả lời trên hoạt động là vì tập hợp các số thực (có chứa số float) chứa tập hợp các số nguyên
Dat Han Bag

@DatHanBag: Và quan trọng hơn, mỗi số nguyên 32 bit được biểu diễn chính xác bởi a double. Trên thực tế, vì điểm nổi của IEEE dựa trên biểu diễn nhị phân / lũy thừa nhị phân, mọi lũy thừa của 2 phải có thể biểu diễn chính xác thậm chí vượt quá 2 ^ 53 (điểm doublekhông thể biểu thị cho mỗi số nguyên tùy ý, 1 đơn vị ở vị trí cuối cùng của mantissa lớn hơn 1.0).
Peter Cordes

@PeterCordes Có tôi đã biết điều đó. Có lẽ tôi nên nói "tập hợp giới hạn" khi đề cập đến tập float và số nguyên cho arduino trong nhận xét của tôi về câu trả lời của
Đạt Han Bag

4
Đây là một câu trả lời có phần hợp lệ cho câu hỏi chung về việc sử dụng pow()cho số nguyên, nhưng arduino AFAICT thậm chí không có điểm nổi phần cứng, vì vậy đó là một câu trả lời khủng khiếp. Một pow()triển khai số nguyên như thế này chạy trong thời gian log2 (n) nhân lên và thêm vào để tích lũy một kết quả gần như chắc chắn sẽ hoạt động tốt hơn và việc không đề cập đến việc dịch chuyển bit có hiệu lực cho 2 chỉ khiến đây là một câu trả lời khủng khiếp cho câu hỏi này.
Peter Cordes

1
@PeterCordes "vì vậy đó là một câu trả lời khủng khiếp". - đồng ý rằng đó là một câu trả lời đơn giản chất lượng thấp. pow () chắc chắn có thể tính toán được trong log2 (n) - phương pháp đơn giản được học ở trường (nhân số của chính nó với sức mạnh không quá hiệu quả). Bạn có thể làm điều đó tốt hơn với một biến đổi Fourier cho các số nguyên thực sự lớn - ví dụ. Nhưng có lẽ OP sẽ chấp nhận và thích nó.
Đạt Han Bag
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.