나는 32 비트 단정도 부동 소수점 정수를 비트 연산 (if 문과 for 루프도 사용할 수 있음)을 사용하여 C로 2로 나눌 것을 요구하는 숙제가 있습니다. float의 비트는 부호없는 정수로 표시되므로 비트 연산자로 수정할 수 있습니다. 제 문제는 분열 중에 비트가 정확히 어떻게되는지 이해하는 데 어려움을 겪고 있다는 것입니다. 내 초기 계획은 부호와 가수 비트를 동일하게 유지하면서 지수 비트를 1만큼 오른쪽으로 시프트하는 것이었지만 효과가 없습니다. 예를 들어, 내 함수에 0x800000으로 표시된 비트가 주어지면 지수를 오른쪽으로 이동하면 모든 비트가 0이되기 때문에 my 함수는 0x00000000을 반환합니다. 그러나 숙제를위한 테스트 드라이버에 따르면이 시나리오에서 정답은 다음과 같습니다. 0x00400000. 이것은 지수 비트가 겉으로보기에는 가수 비트로 어떻게 또는 왜 전환 될지 확실하지 않기 때문에 실제로 혼란 스럽습니다.나누기 중에 float 비트가 어떻게됩니까?
unsigned divideFloatBy2(unsigned uf){
//copy the sign bit
unsigned signBit = (1 << 31) & uf;
//copy mantissa
unsigned mantissa = ~0;
mantissa >>= 9;
mantissa &= uf;
//copy exponent
unsigned mask = 0xFF;
mask <<= 23;
unsigned exponent = (uf & mask);
exponent >>= 23;
exponent >>= 1; //right shift to divide by 2;
exponent <<= 24;
//combine all again
unsigned ret = signBit | exponent | mantissa;
return ret; //will be interpreted as float later
}
이 기능은 위에 제공된 입력과 같이 일부 입력에서는 올바르게 작동하지만 일부 입력에서는 올바르게 작동하지 않습니다. 나는이 코드를 작성하는 것보다 나눗셈 중에 float의 비트가 어떻게되는지에 대해 더 많이 묻는다.
지수의 단순 감소를 통한 IEEE-754'binary32 '값의 2 나누기가 표준화 된 부동 소수점 숫자에 대해서만 올바르게 작동한다는 것을 지적 해 주시겠습니까? 비정규 (subnormals)를 올바르게 처리하려면 추가 확장이 필요합니다. – njuffa
찍은 포인트, @njuffa. 정규화 된 입력에 적용된다는 점을 명확히하기 위해 의견을 수긍했습니다. –