C++实现浮点数与其二进制表示的转换

在计算机里硬件层,只有1和0。如果要表示小数,就必须要做一些转换。浮点数就是这样诞生的。具体如何表示浮点数,网上有很多资料,笔者就毋庸赘述了。

这几天好奇,就用C++写了一个double/float与其二进制互转的程序。经过测试貌似double转换二进制的函数有问题,不过大体思路是对的。下面给出代码。

32位二进制转float

/**
 * @{fun} cunvert binary String to float num
 * @{param} a binary string obj
 */
float binaryToFloat(string & binaryString) {
  int sign = binaryString[0] - '0';
  bitset exponent( string( binaryString.substr(1, 8)  ) );
  bitset mantissa( string( binaryString.substr(9, 23) ) );

  // display some info
  cout << "exponent: " << exponent << ", to unsigned long: " << exponent.to_ulong() << endl;
  cout << "mantissa: " << mantissa << ", to unsigned long: " << mantissa.to_ulong() << endl;

  // show mantissa's true float value
  // (mantissa.to_ulong() + pow(2,23) ) * pow(2, -23) == (mantissa.to_ulong() ) * pow(2, -23) + 1
  cout << "mantissa float: " << (mantissa.to_ulong() + pow(2,23) ) * pow(2, -23) << endl;

  // in the power part, unsigned long must be convert to int
  float result = (mantissa.to_ulong() + pow(2,23) ) * pow(2, -23 + int(exponent.to_ulong() - 127) );

  return sign == 1 ? -result : result;
}

 

64位二进制转double

double binaryToDouble(string & binaryString) {
  int sign = binaryString[0] - '0';
  bitset exponent( string( binaryString.substr(1, 11)  ) );
  bitset mantissa( string( binaryString.substr(12, 52) ) );

  // display some info
  cout << "exponent: " << exponent << ", to unsigned long long: " << exponent.to_ullong() << endl;
  cout << "mantissa: " << mantissa << ", to unsigned long long: " << mantissa.to_ullong() << endl;

  // show mantissa's true float value
  // (mantissa.to_ullong() + pow(2,52) ) * pow(2, -52) == (mantissa.to_ullong() ) * pow(2, -52) + 1
  cout << "mantissa doble: " << (mantissa.to_ullong() + pow(2,52) ) * pow(2, -52) << endl;

  // in the power part, unsigned long must be convert to int
  float result = (mantissa.to_ullong() + pow(2, 52) ) * pow(2, -52 + int(exponent.to_ullong() - 1028) );

  return sign == 1 ? -result : result;
}

至于float/double转二进制倒是颇为简单,直接利用bitset类输出就可以。

float/double转二进制

cout << Float << " to binary: " << bitset<32>(* (unsigned long *) & Float) << endl;
cout << Double << " to binary: " << bitset<64>(* (unsigned long long *) & Double) << endl;

其实Python,JavaScript我都试过,float/double没法直接转二进制,要转比较麻烦,反过来转换也是一样的。毕竟这两门语言不是干这种事的。其他离硬件层远的语言应该也是类似的。

作者: V

Web Dev

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s