在C++中,我有一個bigint類,它可以容納任意大小的整數。將float轉換爲bigint(又名便攜式獲取二進制指數和尾數)
我想將大浮點數或雙數轉換爲bigint。 我有一個工作方法,但它有點破解。我使用IEEE 754數字規範來獲取輸入數字的二進制符號,尾數和指數。
下面是代碼(註冊在這裏忽略不計,這並不重要):
float input = 77e12;
bigint result;
// extract sign, exponent and mantissa,
// according to IEEE 754 single precision number format
unsigned int *raw = reinterpret_cast<unsigned int *>(&input);
unsigned int sign = *raw >> 31;
unsigned int exponent = (*raw >> 23) & 0xFF;
unsigned int mantissa = *raw & 0x7FFFFF;
// the 24th bit is always 1.
result = mantissa + 0x800000;
// use the binary exponent to shift the result left or right
int shift = (23 - exponent + 127);
if (shift > 0) result >>= shift; else result <<= -shift;
cout << input << " " << result << endl;
它的工作原理,但它是相當醜陋,我不知道它是多麼便於攜帶。有一個更好的方法嗎?是否有一種不太醜陋,便攜的方式來從浮點數或雙精度中提取二進制尾數和指數?
感謝您的回答。爲了後代,這是一個使用frexp的解決方案。由於循環效率較低,但它適用於float和double類型,不使用reinterpret_cast或依賴任何有關浮點數表示的知識。
float input = 77e12;
bigint result;
int exponent;
double fraction = frexp (input, &exponent);
result = 0;
exponent--;
for (; exponent > 0; --exponent)
{
fraction *= 2;
if (fraction >= 1)
{
result += 1;
fraction -= 1;
}
result <<= 1;
}
順便說一下,如果你使它成爲'unsigned int raw&= * reinterpret_cast(&input); ',你擺脫了所有其他的解除引用。 –
GManNickG
2010-01-25 16:58:21
該計劃的結果是7.699999752192e13,而不是7.7e13。 正如我在下面的答案中所說的,單行代碼 - 無符號long long float_to_int =(unsigned long long)input; - 給出與你的程序相同的答案。 – 2010-01-26 01:54:30