pow ()에 비 플로트 대안이 있습니까?


9

Arduino 웹 사이트 에서 LANGUAGE REFERENCE를 닦았으며 , pow() 큰 무언가를 놓쳐 야 하는 플로트가 아닌 것을 찾을 수 없었지만, 내 인생에서 나는 혼란에 빠졌습니다! pow()수학 제목 아래의 FUNCTIONS 열에서 (예상 한 것처럼) 찾았 지만 [base] 및 [exponent] 매개 변수는 모두 부동 (float)이라고합니다. 그리고 수학 제목 아래에는 6 개의 다른 항목 만 있습니다. 그들 중 어느 것도 정수 버전 인 것처럼 보이지 않습니다. 내가하고 싶은 것은 0에서 10까지의 지수를 사용하여 2의 거듭 제곱을 생성하는 것입니다. 2 ^ 0 = 1, 2 ^ 1 = 2, 2 ^ 2 = 4, 2 ^ 3 = 8, 2 ^ 4 = 16 2 ^ 5 = 32, 2 ^ 6 = 64, 2 ^ 7 = 128, 2 ^ 8 = 256, 2 ^ 9 = 512, 2 ^ 10은 1024

float을 사용하는 것이 내가 할 수있는 유일한 방법입니까? 나는 현실과 상충되는 것처럼 느끼기 시작했고 실제로 내 약을 세었지만, 나는 내가 있어야 할 곳에 옳았습니다. 시간을 낭비한이 엄청난 감독에 대해 미리 사과 드리지만 9 페이지 분량의 태그를 모두 살펴보고 내가 생각할 수있는 모든 검색을 해보았습니다. 나는 그다지 많은 시간을 소비하지 않았다는 것을 인정할 것이다. 그러나 나는 이것이 단지 5 분의 일과 같을 것이라고 확신했다!


2
정수 pow ()의 일반적인 경우는 stackoverflow.com/questions/101439/…를 참조하십시오 . 2의 거듭 제곱은 교대를 사용하십시오.
Peter Cordes

답변:


8

일반적으로 @dat_ha의 대답은 정확하지만 매우 특별한 경우를 원한다는 점은 주목할 가치가 있습니다. 컴퓨터는 이진 산술을 사용하기 때문에 2의 거듭 제곱과 관련된 작업에는 종종 일부 바로 가기가 있습니다.

숫자에 2의 거듭 제곱을 곱하면 왼쪽 시프트 연산 ( <<)을 통해 문자를 숫자 (즉, 비트)의 이진 표현의 숫자를 왼쪽으로 시프트합니다 . 밑 2에서, 한 자리를 왼쪽으로 이동시키는 비트는 2를 곱하는 것과 동일합니다. 밑 10을 바꾸는 자리에서 1을 왼쪽으로 이동하는 것은 10을 곱하는 것과 같습니다. C ++에서 왼쪽 이동 연산자에 대한 자세한 설명 스택 오버플로 에서이 답변을 참조하십시오 .

왼쪽 이동은 정보를 잃을 수 있습니다. 끝에서 벗어난 비트는 손실됩니다. 2에서 10의 거듭 제곱이 필요하기 때문에 Arduino Uno에서 최대 값을2^15-1 갖는 부호있는 정수로 작업 할 때 안전 합니다.

이러한 경고를 감안할 때 이러한 제약 조건 내에서 2의 거듭 제곱을 계산하는 함수가 있습니다. 왼쪽 시프트 연산이 매우 낮은 수준의 연산이고 실제로 곱셈이 수행되지 않기 때문에 이것은 매우 빠른 코드입니다.

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

오류 :를 사용하면 2 ^ 32-1까지 올라갈 수 있습니다 unsigned long.
Dat Ha

@DatHa 감사합니다, 편집하는 동안 "서명"이라는 단어를 잃어버린 것 같습니다. 결정된.
Jason Clark

1
임의의 정밀 정수 연산의 구현을 사용하면 2 ^
Dat Han Bag

특히 pow () 결과의 정수 변환 결과가 2의 거듭 제곱에 대해 작동하지 않는 이유를 알고 싶습니다. int (pow (2,3))는 7을 반환합니다!
KDM

1

그것은 작동 int, double, longfloat. unsigned long그리고 unsigned int또한 작동합니다. 플로트 만 사용할 필요는 없습니다.

도움이 되었기를 바랍니다.


위의 답변이 효과가있는 이유는 실수 세트 (float 포함)에 정수 세트가 포함되어 있기 때문입니다.
Dat Han Bag

@DatHanBag : 더 중요한 것은 모든 32 비트 정수는 정확히로 표현할 수 있다는 것 double입니다. 실제로 IEEE 부동 소수점은 이진 가수 / 지수 표현을 기반으로하기 때문에 2의 모든 거듭 제곱은 2 ^ 53을 넘어서도 정확하게 표현할 수 있어야합니다 ( double마지막 정수의 모든 위치 를 나타낼 수없는 지점 , 마지막 부분의 1 단위). 가수는 1.0보다 큽니다.
Peter Cordes

@PeterCordes 네, 알고있었습니다. 아마 대답에 대한 내 의견에서 arduino에 대한 부동 및 정수 세트를 언급 할 때 "바운드 세트"라고 말했을 것입니다.
Dat Han Bag

4
이것은 pow()정수 를 사용하는 일반적인 질문에 대한 다소 유효한 대답 이지만 AFAICT arduino에는 하드웨어 부동 소수점조차 없으므로 끔찍한 대답입니다. log2 (n) 시간 곱하기와 결과를 누적하기 위해 추가 pow()하는 것과 같은 정수 구현 은 거의 확실히 더 나은 성능을 발휘할 것입니다 .2의 거듭 제곱에 대한 비트 시프트 작업은이 질문에 대한 끔찍한 대답입니다.
Peter Cordes

1
@PeterCordes는 "끔찍한 대답"입니다. -저품질의 단순한 대답이라고 동의했습니다. pow ()는 log2 (n)에서 확실히 계산할 수 있습니다. 학교에서 배운 간단한 방법입니다 (자체에 힘을 곱하는 방법은 그다지 효율적이지 않습니다). 예를 들어 정말 큰 정수에 대한 푸리에 변환으로 더 잘 수행 할 수 있습니다. 그러나 아마도 OP가 그것을 좋아하고 좋아할 것입니다.
Dat Han Bag 2
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.