![]() |
1
13
下面是几个函数,用于将字符串转换为整数,反之亦然:
这就是你使用它们的方式:
请注意,我在这些例程中没有做太多错误检查(比如检查是否有超出范围的字符)
|
![]() |
2
6
字符串的基本算法->数字是:
这样做通常比在加法之前将每个数字乘以10的右幂更有效。这将需要2倍;一个是增加10的幂,另一个是将其应用于数字。(或以10的升幂查找表格)。
当然
为了提高效率,您可以使用SSSE3
再加上@Michael的答案,int->字符串函数
在第一个非数字处停止
,而不是固定长度。这会捕捉到一些问题,比如当用户按下return键时,字符串中出现了换行符,以及没有旋转
我也做了一些改进:
我更改了寄存器,使其遵循x86-64系统V ABI(RDI中的第一个arg,EAX中的返回)。
移植到32位:
这完全不依赖于64位;只需使用32位寄存器即可将其移植到32位。(即更换
这将停止转换第一个非数字字符。
这通常是终止隐式长度字符串的0字节。通过检查,可以在循环结束后检查它是否是字符串结尾,而不是其他非数字字符
如果输入的是显式长度字符串,则需要使用循环计数器,而不是检查终止符(如@Michael的答案),因为内存中的下一个字节可能是另一个数字。或者它可能位于未映射的页面中。
让第一次迭代变得特别
在跳入循环的主要部分之前处理它被称为
loop peeling
.剥离第一次迭代允许我们特别优化它,因为我们知道total=0,所以不需要将任何值乘以10。就像从
得到
nice loop structure (with the conditional branch at the bottom)
,我在第一次迭代中使用了跳入循环中间的技巧。这甚至不需要额外的钱
解决在非数字上退出循环问题的简单方法是使用
如果我不需要
我首先使用movzx加载零扩展名,而不是在将数字从ASCII转换为整数后进行加载。(必须在某个时候完成,才能添加到32位EAX中)。处理ASCII数字的代码通常使用字节操作数大小,如
有关更多优化内容,请参阅 http://agner.org/optimize , 以及网站上的其他链接 x86 tag wiki . tag wiki也有初学者链接,包括一个FAQ部分,其中包含指向integer->字符串函数和其他常见的初学者问题。 相关的:
|
![]() |
Darky · 多重定义…c++vsCode[重复] 2 年前 |
![]() |
Ty Q. · 分段故障GLFW3/GLAD 2 年前 |
![]() |
Noè Murr · 如何获得C函数的基本编译二进制代码? 2 年前 |
![]() |
AvirukBasak · gcc中无return语句的尾部递归 2 年前 |
![]() |
hepl · gcc如何决定在创建可执行文件时使用dynamics库? 2 年前 |