c++ - 如何在 C++ 中从十六进制切换到 2^16 系统

标签 c++ arrays number-systems

我有这样一个任务: 用户以十六进制输入数字 N1(str1) 和 N2(str2)。该程序必须将数字从十六进制转换为 2^16 系统,并计算 2^16 系统中数字 N1 和 N2 的总和,然后将结果转换为十六进制。

我有这样一个想法: 首先从十六进制转换为十进制(我可以这样做)。 然后取每个数字模 2 ^ 16 以数字 N1dec(dec11)(或 N2dec(dec22))为底 2 ^ 16 的对数,并将余数写入相应的数组。这就是我的问题开始的地方。我从十进制到 2^16 系统的转换不起作用。希望您能提供帮助。

#include <iostream> 
using namespace std;

int main()
{
//HEX to decimal
const char* const str1 = "101D0";//7A120 = 500000; 101D0 = 66000;   //1F4 = 500=dec1=N1
cout << "Hello!\nFirst number in HEX system is " << str1 << endl;
istringstream is(str1);
int dec1;
is >> hex >> dec1;
if (!is && !is.eof()) throw "dammit!";
cout << "First number in decimal system: " << dec1 << endl;
const char* const str2 = "1567";//5479=dec2=num2
cout << "Second number in HEX system is " << str2 << endl;
istringstream iss(str2);
int dec2;
iss >> hex >> dec2;
if (!iss && !iss.eof()) throw "dammit!";
cout << "Second number in decimal system: " << dec2 << endl;
//

//Decimal to 2^16 system
int dec11 = dec1;//because dec11 will be = 0
int dec22 = dec2;//because dec22 will be = 0

int k = 1 << 16;
cout << "2^16 = " << k << endl;
int intPART1 = log(dec11) / log(k);
cout << "Int part of log2^16 (" << dec11 << ") is " << intPART1 << endl << "So num1 in 2^16 system will look like ";

int *n1 = new int[intPART1 + 1];
for (int i = 0; i <= intPART1; i++)
{
    if (i != 0)
    {
        n1[i] = dec11 % k*(1<<16-1);
        dec11 = dec11 / k;
    }
    else
    {
        n1[i] = dec11 % k;
        dec11 = dec11 / k;
    }
}
for (int i = intPART1; i >= 0; i--)
{
    cout << n1[i] << "   ";
}
cout << endl;
int intPART2 = log(dec22) / log(k);
cout << "Int part of log2^16 (" << dec22 << ") is " << intPART2 << endl << "So num2 in 2^16 system will look like ";

int *n2 = new int[intPART2 + 1];
for (int i = 0; i <= intPART2; i++)
{
    if (i != 0)
    {
        n2[i] = dec22 % k*(1 << 16 - 1);
        dec22 = dec22 / k;
    }
    else
    {
        n2[i] = dec22 % k;
        dec22 = dec22 / k;
    }
}

for (int i = intPART2; i >= 0; i--)
{
    cout << n2[i] << "   ";
}
cout << endl;

最佳答案

由于十六进制值是 16 进制的,假设 16^1 和 2^16 可以重新计算为 16^4,我们已经可以看到您的目标基数是源基数的倍数。这使得计算非常简单直接。我们所要做的就是稍微移动一下。

int hexToInt(char c)
{
    if (c >= 'a')
        return c - 'a' + 10;
    if (c >= 'A')
        return c - 'A' + 10;
    return c - '0';
}

// Converts hex to base 2^16. vector[0] holds the MSB.
std::vector<unsigned short> toBase0x10000(std::string const& hex)
{
    std::size_t bufSize = hex.size() / 4 + (hex.size() % 4 > 0);
    std::vector<unsigned short> number(bufSize);

    int shift = 0;
    int value = 0;
    std::size_t numIndex = number.size();

    for (int i = hex.size() - 1; i >= 0; i--)
    {
        value |= hexToInt(hex[i]) << shift;
        shift += 4;

        if (shift == 16)
        {            
            number[--numIndex] = static_cast<unsigned short>(value);
            shift = 0;
            value = 0;
        }
    }

    if (value != 0)
        number[--numIndex] = static_cast<unsigned short>(value);

    return number;
}

std::string fromBase0x10000(std::vector<unsigned short> const& num)
{
    std::stringstream ss;
    for (auto&& digit : num)
        ss << std::hex << digit;
    return ss.str();
}

toBase0x10000返回 std::vector<unsigned short>因此 vector 中的每个元素代表 2^16 基数的一位数(因为 unsigned short 可以准确地保存该值范围)。

作为副作用,此实现支持任何精度数字,因此您不受数字类型值范围的限制,如 intlong .

Here是一个完整的例子。

关于c++ - 如何在 C++ 中从十六进制切换到 2^16 系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58192954/

相关文章:

c++ - 推导可变参数模板参数失败?

c++ - 使用字符串和整数逐行读取文件

c++ - 旋转顶点数组对象不起作用

math - 如何找到十进制数的10的补码

algorithm - 无进位加法的复杂性

java - System.out.println() 如何处理二进制数据?

c++ - VS2017 和 VS2015 之间的链接器有区别吗?

c++ - QSettings:是否可以禁用组?

java - 如何检查数组元素是否为空以避免Java中的NullPointerException

arrays - Numpy 数组内存管理