【问题标题】:Convert negative binary number to decimal将负二进制数转换为十进制
【发布时间】:2018-03-03 07:26:48
【问题描述】:

例如:

string binaryValue = "11111111111111111111111111111011" // -5

我需要将此字符串转换为该数字的十进制表示。

stoi(binaryValue, nullptr, 2)

在这种情况下会抛出异常。那么我怎么能在 C++ 中做到这一点? String 或 int 无关紧要。

【问题讨论】:

  • 有什么例外?
  • Microsoft C++ exception: std::out_of_range at memory location 0x00BDF664.
  • 您的转换取决于 2 补码表示,这不是 C++ 标准的一部分。因此,数字超出范围。使用stol 并强制转换为int

标签: c++ binary twos-complement


【解决方案1】:

the documentation

int  std::stoi( const std::string& str, std::size_t* pos = 0, int base = 10 );

特别是:

[str] 的有效整数值由以下部分组成:

  • (可选)加号或减号

...

...

如果减号是输入序列的一部分,则计算出的数值 从数字序列中取反,就像结果类型中的一元减号一样。

例外情况

  • std::invalid_argument如果无法执行转换

  • std::out_of_range 如果转换后的值超出范围 结果类型...

如果前面没有减号,则字符串:

std::string binaryValue = "11111111111111111111111111111011";

将在调用中解释:

std::stoi(binaryValue, nullptr, 2);

以 base-2 表示的非负整数值。但就这样, 它超出了范围,所以 std::out_of_range 被抛出:

将 -5 表示为一个字符串,您的 std::stoi 调用将按照您的预期进行转换, 使用:

std::string const binaryValue = "-101";

Live demo

如果您不想在非负以 2 为基数的数字前加上减号,或者在现实世界中无法这样做 情况,但希望解释"11111111111111111111111111111011" 作为使用std::sto* API 的有符号整数的二进制补码表示, 那么您必须首先将字符串转换为足够宽的 unsigned 整数 类型,然后将该无符号值转换为有符号值。例如

#include <string>
#include <iostream>

int main()
{
    auto ul = std::stoul("11111111111111111111111111111011",nullptr,2);
    std::cout << ul << std::endl;
    int i = ul;
    std::cout << i << std::endl;
    return 0;
}

Live demo

【讨论】:

  • unsigned 转换为int 的值太大而无法存储在int 中的结果是实现定义的。
【解决方案2】:

您可能知道数字存储为二进制补码
使用简单的伪代码进行转换

从左边翻转数字 0->1, 1->0 来写 util 你在字符串中找到最后一个 1 不要切换这个

这将是你的答案 0000000000000000000000000101=5


这是来自https://www.geeksforgeeks.org/efficient-method-2s-complement-binary-string/的代码

#include<bits/stdc++.h>
using namespace std;


string findTwoscomplement(string str)
{


  int n = str.length();


// Traverse the string to get first '1' from
// the last of string
int i;
for (i = n ; i >= 0 ; i--)
    if (str[i] == '1')
        break;

// If there exists no '1' concat 1 at the
// starting of string
if (i == 0)
    return '1' + str;

// Continue traversal after the position of
// first '1'
for (int k = i-1 ; k >= 0; k--)
{
    //Just flip the values
    if (str[k] == '1')
        str[k] = '0';
    else
        str[k] = '1';
}

// return the modified string
return str;;
}



int main()
{
    string str = "11111111111111111111111111111011";
    cout << findTwoscomplement(str);
//now you convert it to decimal if you want
    cout<<"Hello World";
    cout << stoul( findTwoscomplement(str),nullptr,2);
        return 0;


     }  

https://onlinegdb.com/SyFYLVtdf预览

【讨论】:

  • 好的,-25 = "11111111111111111111111111100111" , 25 = "000000000000000000000000000011001" 你的解决方案对我不起作用。
  • 我从 geeksforgeeks 带来了植入,如果喜欢请接受回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2019-04-26
  • 2010-12-08
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
相关资源
最近更新 更多