简体   繁体   English

HTOI不正确的10位数字输出

[英]Htoi incorrect output at 10 digits

When I input 0x123456789 I get incorrect outputs, I can't figure out why. 当我输入0x123456789时,我得到了错误的输出,我不知道为什么。 At first I thought it was a max possible int value problem, but I changed my variables to unsigned long and the problem was still there. 起初我以为这是最大可能的int值问题,但是我将变量更改为unsigned long,但问题仍然存在。

#include <iostream>
using namespace std;

long htoi(char s[]);

int main()
{
    cout << "Enter Hex \n";
    char hexstring[20];
    cin >> hexstring;
    cout << htoi(hexstring) << "\n";

}

//Converts string to hex
long htoi(char s[])
{
    int charsize = 0;
    while (s[charsize] != '\0')
    {
        charsize++;
    }
    int base = 1;
    unsigned long total = 0;
    unsigned long multiplier = 1;
    for (int i = charsize; i >= 0; i--)
    {
        if (s[i] == '0' || s[i] == 'x' || s[i] == 'X' || s[i] == '\0')
        {
            continue;
        }
        if ( (s[i] >= '0') && (s[i] <= '9') )
        {
            total = total + ((s[i] - '0') * multiplier);
            multiplier = multiplier * 16UL;
            continue;
        }
        if ((s[i] >= 'A') && (s[i] <= 'F'))
        {
            total = total + ((s[i] - '7') * multiplier); //'7' equals 55 in decimal, while 'A' equals 65
            multiplier = multiplier * 16UL;
            continue;
        }
        if ((s[i] >= 'a') && (s[i] <= 'f'))
        {
            total = total + ((s[i] - 'W') * multiplier); //W equals 87 in decimal, while 'a' equals 97
            multiplier = multiplier * 16UL;
            continue;
        }
    }
    return total;
}

long probably is 32 bits on your computer as well. long可能是您的计算机上运行32位的为好。 Try long long . long long尝试。

You need more than 32 bits to store that number. 您需要超过32位才能存储该数字。 Your long type could well be as small as 32 bits. 您的long类型可能只有32位。

Use a std::uint64_t instead. 请改用std :: uint64_t。 This is always a 64 bit unsigned type. 这始终是64位无符号类型。 If your compiler doesn't support that, use a long long. 如果您的编译器不支持,请使用long long。 That must be at least 64 bits. 那必须至少是64位。

The idea follows the polynomial nature of a number. 这个想法遵循数字的多项式性质。 123 is the same as 123与

1*10 2 + 2*10 1 + 3*10 0 1 * 10 2 + 2 * 10 1 + 3 * 10 0

In other words, I had to multiply the first digit by ten two times . 换句话说,我必须将第一个数字乘以十两次 I had to multiply 2 by ten one time . 我必须将2乘以10 一次 And I multiplied the last digit by one. 然后我将最后一位乘以1。 Again, reading from left to right: 同样,从左至右阅读:

  • Multiply zero by ten and add the 1 → 0*10+1 = 1. 零乘以10并加1→0 * 10 + 1 = 1。
  • Multiply that by ten and add the 2 → 1*10+2 = 12. 将其乘以十,然后将2→1 * 10 + 2 = 12。
  • Multiply that by ten and add the 3 → 12*10+3 = 123. 将其乘以十,然后加上3→12 * 10 + 3 = 123。

We will do the same thing: 我们将做同样的事情:

#include <cctype>
#include <ciso646>
#include <iostream>
using namespace std;

unsigned long long hextodec( const std::string& s )
{
  unsigned long long result = 0;
  for (char c : s)
  {
    result *= 16;
    if (isdigit( c )) result |= c - '0';
    else              result |= toupper( c ) - 'A' + 10;
  }
  return result;
}

int main( int argc, char** argv )
{
  cout << hextodec( argv[1] ) << "\n";
}

You may notice that the function is more than three lines. 您可能会注意到该函数超过三行。 I did that for clarity. 我这样做是为了清楚起见。 C++ idioms can make that loop a single line: C ++习惯用法可以使该循环成为一行:

for (char c : s)
  result = (result << 4) | (isdigit( c ) ? (c - '0') : (toupper( c ) - 'A' + 10));

You can also do validation if you like. 您也可以根据需要进行验证。 What I have presented is not the only way to do the digit-to-value conversion. 我介绍的内容并不是进行数字到值转换的唯一方法 There exist other methods that are just as good (and some that are better). 还有其他一些方法一样好(还有一些更好)。

I do hope this helps. 我希望这会有所帮助。

I found out what was happening, when I inputted "1234567890" it would skip over the '0' so I had to modify the code. 我发现了什么情况,当我输入“ 1234567890”时,它将跳过“ 0”,因此我必须修改代码。 The other problem was that long was indeed 32-bits, so I changed it to uint64_t as suggested by @Bathsheba. 另一个问题是long确实是32位,因此我按照@Bathsheba的建议将其更改为uint64_t。 Here's the final working code. 这是最终的工作代码。

#include <iostream>
using namespace std;

uint64_t htoi(char s[]);

int main()
{
    char hexstring[20];
    cin >> hexstring;
    cout << htoi(hexstring) << "\n";

}

//Converts string to hex
uint64_t htoi(char s[])
{
    int charsize = 0;
    while (s[charsize] != '\0')
    {
        charsize++;
    }
    int base = 1;
    uint64_t total = 0;
    uint64_t multiplier = 1;
    for (int i = charsize; i >= 0; i--)
    {
        if (s[i] == 'x' || s[i] == 'X' || s[i] == '\0')
        {
            continue;
        }
        if ( (s[i] >= '0') && (s[i] <= '9') )
        {
            total = total + ((uint64_t)(s[i] - '0') * multiplier);
            multiplier = multiplier * 16;
            continue;
        }
        if ((s[i] >= 'A') && (s[i] <= 'F'))
        {
            total = total + ((uint64_t)(s[i] - '7') * multiplier); //'7' equals 55 in decimal, while 'A' equals 65
            multiplier = multiplier * 16;
            continue;
        }
        if ((s[i] >= 'a') && (s[i] <= 'f'))
        {
            total = total + ((uint64_t)(s[i] - 'W') * multiplier); //W equals 87 in decimal, while 'a' equals 97
            multiplier = multiplier * 16;
            continue;
        }
    }
    return total;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM