Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 快速ascii块到整数_C++ - Fatal编程技术网

C++ 快速ascii块到整数

C++ 快速ascii块到整数,c++,C++,stl中是否有任何命令可以将ascii数据转换为十六进制表示的整数形式?例如:abc->0x616263 我有我能想到的最基本的方法: uint64_t tointeger(std::string){ std::string str = "abc"; uint64_t value = 0; // allow max of 8 chars for(int x = 0; x < str.size(); x++) valu

stl中是否有任何命令可以将ascii数据转换为十六进制表示的整数形式?例如:abc->0x616263

我有我能想到的最基本的方法:

uint64_t tointeger(std::string){
    std::string str = "abc";
    uint64_t value = 0;                  // allow max of 8 chars
    for(int x = 0; x < str.size(); x++)
        value = (value << 8) + str[x];
    return value;
}
如上所述:tointegerabc;返回值0x616263

但这太慢了。因为我不得不使用这个函数数十万次,它大大减慢了我的程序。有4到5个函数依赖于这个函数,除了这个函数被调用了数千次之外,每个函数都被调用了数千次

有什么更快的方法可以做到这一点?

您尝试过多字符常量吗?即

你试过多字符常量吗?即


做某事最快的方法就是根本不做

也许您可以将数据存储为整数,并仅在必要时将其转换为字符串?您还需要将数据转换成百上千次吗


如果您真的需要,我可能会使用一个简单的固定大小数组而不是字符串来展开循环。但这是一种微观优化,在大多数情况下,最好是找到一种不同的方法来做你想做的事情。

最快的方法就是根本不去做

也许您可以将数据存储为整数,并仅在必要时将其转换为字符串?您还需要将数据转换成百上千次吗


如果您真的需要,我可能会使用一个简单的固定大小数组而不是字符串来展开循环。但这是一种微观优化,在大多数情况下,最好是找到一种不同的方法来完成您试图完成的任务。

编辑:重读这个问题,其目的似乎是对最多8个字符的字符串进行BCD式的转换,除了对每个字符使用8位而不是4位

您的方法看起来很合理,或者您可以像在big-endian上一样使用memcpy字符串,您必须在little-endian上反转字符串


但是,如果这是您的性能瓶颈,我认为您可能希望重新考虑为什么需要这样做数十万次。也许对算法进行根本性的更改将产生比尝试微观优化转换更大的性能提升。例如,在内部将值存储为uint64_t,并且仅在显示/接口需要时转换为字符串形式。或者,只需将其永久存储为字符串,并消除将其转换为伪BCD格式的需要。

编辑:重新阅读问题,其目的似乎是将BCD格式转换为最多8个字符的字符串,但每个字符使用8位而不是4位

您的方法看起来很合理,或者您可以像在big-endian上一样使用memcpy字符串,您必须在little-endian上反转字符串


但是,如果这是您的性能瓶颈,我认为您可能希望重新考虑为什么需要这样做数十万次。也许对算法进行根本性的更改将产生比尝试微观优化转换更大的性能提升。例如,在内部将值存储为uint64_t,并且仅在显示/接口需要时转换为字符串形式。或者,只需将其永久存储为字符串,无需将其转换为伪BCD格式。

您需要将字符串中的ASCII字符打包为64位整数

由于std::string不是固有类型,为了安全起见,请将数据复制到缓冲区:

uint_64 values[100]; // Allocate memory on a 64-bit boundary.

char * p = (char *) values; // Point to the memory as characters.

std::string example("beethoven");

std::copy(example.c_str(), p, example.length();
只要对齐,复制就更安全。为了更快,但更危险,只需避免复制:

  uint_64 danger;
  danger = *((uint_64 *) example.c_str());
std::string::c_str方法返回指向文本的c样式字符串表示形式的指针,但是文本不能保证永远持续,因此需要复制。此外,指针仅保证位于字符对齐上。因此,如果它恰好位于地址0x1003处,则处理器可能会生成校准故障或速度减慢,因为它必须在未对齐的边界处进行提取

编辑1:
此方法不考虑端性。该方法使用平台的端点。更改Endianness会降低性能。

您希望将字符串中的ASCII字符打包为64位整数

由于std::string不是固有类型,为了安全起见,请将数据复制到缓冲区:

uint_64 values[100]; // Allocate memory on a 64-bit boundary.

char * p = (char *) values; // Point to the memory as characters.

std::string example("beethoven");

std::copy(example.c_str(), p, example.length();
只要对齐,复制就更安全。为了更快,但更危险,只需避免复制:

  uint_64 danger;
  danger = *((uint_64 *) example.c_str());
std::string::c_str方法返回指向文本的c样式字符串表示形式的指针,但是文本不能保证永远持续,因此需要复制。此外,指针仅保证位于字符对齐上。因此,如果它恰好位于地址0x1003处,则处理器可能会生成校准故障或速度减慢,因为它必须在未对齐的边界处进行提取

编辑1: 此方法不考虑端性。该方法使用平台的端点。变端性
将降低性能。

如果对字符串的存储方式有限制,则可以将数据直接转换为int或long。如果您知道字符串在结尾处填充了NULL 0字节,以至少8字节对齐,那么下面的方法就行了

uint64_t value = *(*unint64_t)str;
您当前的代码片段本身并没有任何低效之处。操作并不缓慢。由于允许的最大字符数为8,因此可以使用开关大小写和循环展开

uint64_t value = 0;
switch(str.size()) {
    case 0:
        value = 0;
        break;
    case 1: // the 2nd char is a null anyways
    case 2:
        value = *(*uint16_t)str;
        break;
    case 3: // the 4th char would be null
    case 4:
        value = *(*uint32_t)str;
        break;
    case 5:
    case 6:
        value = *(*uint32_t)str + *((*uint16_t)(str+4));
        break;
    case 7:
    case 8:
    default: // 8 or more do the first 8 
        value = *(*uint64_t)str;
        break;
}
因为我们使用switch-case语句,所以编译后的代码将是一个跳转表,而不是一个循环,其中每个迭代都需要一个比较操作。此外,因为我们将内存强制转换为不同的类型,所以不需要分别循环每个字符串/字节。 记忆值 0x8000 0x65,0x66,0x67,0x00->abc,0 大小为3,但空终止符使其长度为4字节,因此我们可以将内存值直接转换为uint32


<>我不在C++中编码,所以希望转换语义学是正确的。

< P>如果你对字符串的存储有限制,你可以直接把数据转换成int或长。如果您知道字符串在结尾处填充了NULL 0字节,以至少8字节对齐,那么下面的方法就行了

uint64_t value = *(*unint64_t)str;
您当前的代码片段本身并没有任何低效之处。操作并不缓慢。由于允许的最大字符数为8,因此可以使用开关大小写和循环展开

uint64_t value = 0;
switch(str.size()) {
    case 0:
        value = 0;
        break;
    case 1: // the 2nd char is a null anyways
    case 2:
        value = *(*uint16_t)str;
        break;
    case 3: // the 4th char would be null
    case 4:
        value = *(*uint32_t)str;
        break;
    case 5:
    case 6:
        value = *(*uint32_t)str + *((*uint16_t)(str+4));
        break;
    case 7:
    case 8:
    default: // 8 or more do the first 8 
        value = *(*uint64_t)str;
        break;
}
因为我们使用switch-case语句,所以编译后的代码将是一个跳转表,而不是一个循环,其中每个迭代都需要一个比较操作。此外,因为我们将内存强制转换为不同的类型,所以不需要分别循环每个字符串/字节。 记忆值 0x8000 0x65,0x66,0x67,0x00->abc,0 大小为3,但空终止符使其长度为4字节,因此我们可以将内存值直接转换为uint32



< >我不在C++中编码,所以希望转换语义正确。我被告知这不起作用,所以我从来没有尝试过,我只是用gcc在我的an intel和ppc Mac上进行了测试,在这里效果很好。我一定要测试,看看你的编译器是否能处理它,字节顺序是否正确。这最多可以处理四个字符。我如何将其转换为接受任意字符串?string/*或char*/str=abc;int value=str不起作用不,这只在编译时起作用。那有效吗????我被告知这不起作用,所以我从来没有尝试过,我只是用gcc在我的an intel和ppc Mac上进行了测试,在这里效果很好。我一定要测试,看看你的编译器是否能处理它,字节顺序是否正确。这最多可以处理四个字符。我如何将其转换为接受任意字符串?string/*或char*/str=abc;int value=str不起作用不,这只在编译时起作用。这正是我没有要求的答案。很难看到你真正要求的答案,当然,我从来没有明确说明应该避免什么,也没有在这个问题上设置任何实际参数。我确实展示了一个例子,它确实做到了代码没有做到的事情:a应该变成0x61,而不是0xa。如果我想要10,我会输入字符串\x0ath,它只取char值,而不是十六进制表示的整数形式。您的问题询问十六进制字符串的整数形式,其中x0A变为10。如果这不是你想要的,你可能想重新措辞这个问题。此外,这不是我的代码,甚至不是我的答案这正是我没有要求的答案很难看出你在哪里要求任何真正的答案,当然也从来没有指定要避免什么或在问题上设置任何真正的参数。我确实展示了一个例子,它做了你的代码没有做的事情:a应该变成0x61,不是0xa。如果我想要10,我会输入字符串\x0ath,它只取char值,而不是十六进制表示的整数形式。您的问题询问十六进制字符串的整数形式,其中x0A变为10。如果这不是你想要的,你可能想重新措辞这个问题。而且,这不是我的代码,甚至不是我的答案。我觉得很有趣,他认为这大大减慢了他的程序……好吧。。。。我应该怎么说呢?你应该准确地说出你想要的是什么,十六进制输入是如何形成的,除了这个基本的方法,你还尝试了什么,这当然不是我能想到的最基本的方法,为什么它慢,有多慢,等等。形成一个适当的问题。这样更好吗?还有@blindy:我知道我需要优化很多,所以我一次一个地完成每个函数。你在运行调试构建吗?您是否尝试过缓存str.size的值?有多慢是非常慢?我觉得有趣的是,他认为这大大减慢了他的程序…好吧。。。。我应该怎么说呢?你应该准确地说出你想要的是什么,十六进制输入是如何形成的,除了这个基本的方法,你还尝试了什么,这当然不是我能想到的最基本的方法,为什么它慢,有多慢,等等。形成一个适当的问题
这更好吗?还有@blindy:我知道我需要优化很多,所以我一次一个地完成每个函数。你在运行调试构建吗?您是否尝试过缓存str.size的值?速度有多慢?写入p然后读取值是否违反严格别名?@Mark:请解释严格别名。并举例说明。同样,我不确定它是否适用于这里,因为p是一个字符*并且理论上允许指向任何类型。该死。我在寻找:如果我把它从左到右读作abc,我期望的值是0x616263。我不希望它在任何机器上变成0x636261如果你想要正确的字节顺序,那么你的解决方案是个好主意。写入p然后读取值是否违反严格别名?@Mark:请解释严格别名。并举例说明。同样,我不确定它是否适用于这里,因为p是一个字符*并且理论上允许指向任何类型。该死。我在寻找:如果我把它从左到右读作abc,我期望的值是0x616263。我不希望它在任何机器上变成0x636261如果您想要正确的字节顺序,那么您的解决方案是一个好主意。