C++ 在C+中,不使用外部库将字符数组中的128位转换为十进制+;

C++ 在C+中,不使用外部库将字符数组中的128位转换为十进制+;,c++,decimal,bit,C++,Decimal,Bit,我必须将一个大小为16(每个字符1字节)的字符数组的128位转换为十进制和十六进制,而不使用所包含的任何其他库。将其转换为十六进制是很容易的,因为每次生成一个字符串时,都会处理四位,并在生成结果后立即为每四位打印结果 但说到小数点。用普通的数学方法转换它是不可能的,在这种方法中,每一位都乘以2,即从左到右的位索引的幂 所以我想把它转换成十六进制,一位数一位数地打印。但问题是,在十进制中,它是不可能的,因为最大数字是9,它需要4位来表示,而4位可以表示多达15位的十进制数。我试着制作一些机械装置来

我必须将一个大小为16(每个字符1字节)的字符数组的128位转换为十进制和十六进制,而不使用所包含的任何其他库。将其转换为十六进制是很容易的,因为每次生成一个字符串时,都会处理四位,并在生成结果后立即为每四位打印结果

但说到小数点。用普通的数学方法转换它是不可能的,在这种方法中,每一位都乘以2,即从左到右的位索引的幂

所以我想把它转换成十六进制,一位数一位数地打印。但问题是,在十进制中,它是不可能的,因为最大数字是9,它需要4位来表示,而4位可以表示多达15位的十进制数。我试着制作一些机械装置来承载附加部件,但找不到这样做的方法。我想,这也行不通。我已经漫无目的地试了三天,因为我不知道该怎么办。甚至在互联网上找不到任何有用的解决方案

所以,我想要一些方法来完成这件事

这是我的完整代码:

#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

const int strng = 128;
const int byts = 16;

class BariBitKari {

    char bits_ar[byts];

public:

    BariBitKari(char inp[strng]) {

        set_bits_ar(inp);
    }

    void set_bits_ar(char in_ar[strng]) {
        char b_ar[byts];

        cout << "Binary 1: ";
        for (int i=0, j=0; i<byts; i++) {

            for (int k=7; k>=0; k--) {
                if (in_ar[j] == '1') {
                    cout << '1';
                    b_ar[i] |= 1UL << k;
                }
                else if (in_ar[j] == '0') {
                    cout << '0';
                    b_ar[i] &= ~(1UL << k);
                }

                j++;
            }
        }
        cout << endl;

        strcpy(bits_ar, b_ar);
    }

    char * get_bits_ar() {
        return bits_ar;
    }


    // Functions

    void print_deci() {

        char b_ar[byts];

        strcpy(b_ar, get_bits_ar());

        int sum = 0;
        int carry = 0;

        cout << "Decimal : ";

        for (int i=byts-1; i >= 0; i--){

            for (int j=4; j>=0; j-=4) {

                char y = (b_ar[i] << j) >> 4;

                // sum = 0;

                for (int k=0; k <= 3; k++) {

                    if ((y >> k) & 1) {
                        sum += pow(2, k);
                    }
                }

                // sum += carry;
                // if (sum > 9) {
                //  carry = 1;
                //  sum -= 10;
                // }
                // else {
                //  carry = 0;
                // }
                // cout << sum;
            }
        }

        cout << endl;
    }

    void print_hexa() {

        char b_ar[byts];

        strcpy(b_ar, get_bits_ar());

        char hexed;

        int sum;

        cout << "Hexadecimal : 0x";

        for (int i=0; i < byts; i++){

            for (int j=0; j<=4; j+=4) {

                char y = (b_ar[i] << j) >> 4;

                sum = 0;

                for (int k=3; k >= 0; k--) {

                    if ((y >> k) & 1) {
                        sum += pow(2, k);
                    }
                }

                if (sum > 9) {
                    hexed = sum + 55;
                }
                else {
                    hexed = sum + 48;
                }
                cout << hexed;
            }
        }
        cout << endl;
    }
};

int main() {

    char ar[strng];

    for (int i=0; i<strng; i++) {
        if ((i+1) % 8 == 0) {
            ar[i] = '0';
        }
        else {
            ar[i] = '1';
        }
    }

    BariBitKari arr(ar);
    arr.print_hexa();
    arr.print_deci();

    return 0;
}
#包括
#包括
#包括
使用名称空间std;
常数int strng=128;
常量int byts=16;
BariBitKari类{
字符比特(byts);
公众:
BariBitKari(字符输入[strng]){
设置位(inp);
}
无效集\u位\u ar(字符串中的字符[strng]){
char b_ar[byts];

cout要将128位数字转换为“十进制”字符串,我将假设大的十进制值只需要包含在字符串中,并且我们只在“正数”中在不使用适当的大数字库的情况下,我将演示一种将任何字节数组转换为十进制字符串的方法。这不是最有效的方法,因为它会不断解析、复制和扫描数字字符字符串

我们将利用以下任何大数字:

0x87654321 == 2,271,560,481
可以转换为以8位块移位的一系列字节。将这些移位的块加回去将得到原始值

0x87 << 24   == 0x87000000 == 2,264,924,160
0x65 << 16   == 0x00650000 ==     6,619,136
0x43 << 8    == 0x00004300 ==        17,152
0x21 << 0    == 0x00000021 ==            33

Sum          == 0x87654321 == 2,271,560,481
然后将字节数组转换为十进制字符串:

// s is a string of digits only (interpreted as decimal number)
// This function will "shift left" the string by N bits
// Basically "multiplying by 2" N times
string ShiftLeftString(const string& s, size_t N)
{
    string result = s;

    while (N > 0)
    {
        result = SumStringValues(result, result); // multiply by 2
        N--;
    }
    return result;
}
string MakeStringFromByteArray(unsigned char* data, size_t len)
{
    string result = "0";
    for (size_t i = 0; i < len; i++)
    {
        auto tmp = to_string((unsigned int)data[i]);   // byte to decimal string
        tmp = ShiftLeftString(tmp, (len - i - 1) * 8); // shift left
        result = SumStringValues(result, tmp);         // sum
    }
    return result;
}
以上打印:
179971563002487956319748178665913454865

我们将使用python对结果进行双重检查:

Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:37:02) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> int("0x87654321aabbccddeeff432124681111", 16)
179971563002487956319748178665913454865
>>>
我觉得不错


我最初有一个实现,可以在32位块而不是8位块中进行分块和求和。但是,会涉及到小端字节顺序和大端字节顺序的问题。我将把这种潜在的优化留作练习,改天再做。

将128位数字转换为“十进制”string,我将假设大的十进制值只需要包含在一个字符串中,并且我们只在“正数”中在不使用适当的大数字库的情况下,我将演示一种将任何字节数组转换为十进制字符串的方法。这不是最有效的方法,因为它会不断解析、复制和扫描数字字符字符串

我们将利用以下任何大数字:

0x87654321 == 2,271,560,481
可以转换为以8位块移位的一系列字节。将这些移位的块加回去将得到原始值

0x87 << 24   == 0x87000000 == 2,264,924,160
0x65 << 16   == 0x00650000 ==     6,619,136
0x43 << 8    == 0x00004300 ==        17,152
0x21 << 0    == 0x00000021 ==            33

Sum          == 0x87654321 == 2,271,560,481
然后将字节数组转换为十进制字符串:

// s is a string of digits only (interpreted as decimal number)
// This function will "shift left" the string by N bits
// Basically "multiplying by 2" N times
string ShiftLeftString(const string& s, size_t N)
{
    string result = s;

    while (N > 0)
    {
        result = SumStringValues(result, result); // multiply by 2
        N--;
    }
    return result;
}
string MakeStringFromByteArray(unsigned char* data, size_t len)
{
    string result = "0";
    for (size_t i = 0; i < len; i++)
    {
        auto tmp = to_string((unsigned int)data[i]);   // byte to decimal string
        tmp = ShiftLeftString(tmp, (len - i - 1) * 8); // shift left
        result = SumStringValues(result, tmp);         // sum
    }
    return result;
}
以上打印:
179971563002487956319748178665913454865

我们将使用python对结果进行双重检查:

Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:37:02) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> int("0x87654321aabbccddeeff432124681111", 16)
179971563002487956319748178665913454865
>>>
我觉得不错


我最初有一个实现,它将在32位块中代替8位块进行块和求和。但是,很少有字节数与大字节字节顺序问题有关。我将把这个潜在的优化作为一个练习来做另一天。< /P>你可能需要一个大的库,作为标准C++没有一个128位整数N。umber。您的编译器可能有一个,但您需要检查文档。@ThomasMatthews我不允许为此使用任何库。您必须自己一个字节一个字节地实现一个基本的长除法算法。Stackoverflow上的任何人都很难为您编写所有代码。相反,您必须尝试实现如果您在实现过程中遇到困难,请自己动手,并询问与编程相关的具体问题,解释您到底遇到了什么困难。只需问问自己,您在小学时是如何学习长除法的?您也是这样做的,但这次使用的是字节,而不是十进制数字。我将创建一个数组

char[128][39]
然后填充2次幂的十进制表示,其中每个字符都是0-9之间的值。因此,向量是2次幂的十进制等价物(与位位置相同)。然后只需遍历每个顺序位,如果是1,则在该位置添加向量,然后通过处理carry(溢出超过9)非常简单,你可以使用CONTXPRPR创建初始集,所以应该相当快。你可能需要一个大的库,因为标准C++没有128位整数。你的编译器可能有一个,但是你需要检查文档。@ ToMasMatthWe我不允许为此使用任何库。你必须实现B。asic长除法算法,一个字节一个字节。Stackoverflow上的任何人是否会为您编写所有代码都是非常值得怀疑的。相反,您必须尝试自己实现它,如果在实现过程中遇到困难,请询问与编程相关的具体问题,解释您到底遇到了什么困难。只需问问自己,如何你在小学学过长除法吗?你也是这样做的,但这次用字节代替十进制数字。我会创建一个数组
char[128][39]
然后用幂2的十进制表示法填充它,其中每个char是0-9之间的值。所以向量是2的幂的十进制等价物(sam)