如何在C中将128位整数转换为十进制ascii字符串?
我正在尝试将存储为 4 个无符号整数数组的 128 位无符号整数转换为 C 中的十进制字符串表示形式:(
unsigned int src[] = { 0x12345678, 0x90abcdef, 0xfedcba90, 0x8765421 };
printf("%s", some_func(src)); // gives "53072739890371098123344"
上面的输入和输出示例完全是虚构的;我不知道该输入会产生什么。)
如果我要使用十六进制、二进制或八进制,这将是一个简单的掩码和位移位以剥离最不重要的字符的问题。然而,在我看来,我需要进行 10 进制除法。不幸的是,我不记得如何跨多个整数执行此操作,并且我使用的系统不支持大于 32 位的数据类型,因此不可能使用 128 位类型。使用不同的语言也已经过时了,我宁愿避免仅仅为了这个操作而使用大量的库。
I'm trying to convert a 128-bit unsigned integer stored as an array of 4 unsigned ints to the decimal string representation in C:
unsigned int src[] = { 0x12345678, 0x90abcdef, 0xfedcba90, 0x8765421 };
printf("%s", some_func(src)); // gives "53072739890371098123344"
(The input and output examples above are completely fictional; I have no idea what that input would produce.)
If I was going to hex, binary or octal, this would be a simple matter of masks and bit shifts to peel of the least significant characters. However, it seems to me that I need to do base-10 division. Unfortunately, I can't remember how to do that across multiple ints, and the system I'm using doesn't support data types larger than 32-bits, so using a 128-bit type is not possible. Using a different language is also out, and I'd rather avoid a big number library just for this one operation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
不需要除法:
输出:
Division is not necessary:
Output:
直接除法基数 2^32,以相反顺序打印十进制数字,使用 64 位算术,复杂度
O(n)
,其中n
是表示形式中的十进制数字位数:编辑:更正了循环,以便在数组
a
只包含零时显示0
。另外,数组是从左到右读取的,a[0] 是最高有效位,a[3] 是最低有效位。
Straightforward division base 2^32, prints decimal digits in reverse order, uses 64-bit arithmetic, complexity
O(n)
wheren
is the number of decimal digits in the representation:EDIT: Corrected the loop so it displays a
0
if the arraya
contains only zeros.Also, the array is read left to right, a[0] is most-significant, a[3] is least significant digits.
一种缓慢但简单的方法是使用减法从最高有效位到最低有效位打印数字。基本上,您需要一个函数来检查是否
x >= y
,并需要另一个函数来计算x -= y
(如果是这种情况)。然后你可以开始计算你可以减去多少次10^38(这将是最高有效数字),然后你可以减去多少次10^37......一直到你可以减去多少次1。
以下是这种方法的完整实现:
问题文本中的十进制数字变为
并且Python同意这是正确的值(这当然并不意味着代码是正确的!;-))
A slow but simple approach is to just printing digits from most significant to least significant using subtraction. Basically you need a function for checking if
x >= y
and another for computingx -= y
when that is the case.Then you can start counting how many times you can subtract 10^38 (and this will be most significant digit), then how many times you can subtract 10^37 ... down to how many times you can subtract 1.
The following is a full implementation of this approach:
That number in the problem text in decimal becomes
and Python agrees this is the correct value (this of course doesn't mean the code is correct!!! ;-) )
同样的事情,但是使用 32 位整数算术:
Same thing, but with 32-bit integer arithmetic:
您实际上不需要实现长除法。您需要实现 2 的幂乘法和加法。您有四个
uint_32
。首先将它们每个都转换为字符串。将它们乘以(2^32)^3
、(2^32)^2
、(2^32)^1
和 < code>(2^32)^0 分别,然后将它们相加。您不需要进行基本转换,只需将四个部分放在一起即可。显然,您需要确保字符串可以处理最多UINT_32_MAX*(2^32)^3
的数字。You actually don't need to implement long division. You need to implement multiplication by a power of two, and addition. You have four
uint_32
. First convert each of them to a string. Multiply them by(2^32)^3
,(2^32)^2
,(2^32)^1
, and(2^32)^0
respectively, then add them together. You don't need to do the base conversion, you just need to handle putting the four pieces together. You'll obviously need to make sure the strings can handle a number up toUINT_32_MAX*(2^32)^3
.假设您有一个快速的 32 位乘法和除法,通过实现 bigint 除法/模 10000,然后使用 (s)printf 输出数字组,可以一次计算 4 位数字的结果。
这种方法也很容易扩展到更高(甚至可变)的精度......
Supposing you have a fast 32-bit multiplication and division the result can be computed 4 digits at a time by implementing a bigint division/modulo 10000 and then using (s)printf for output of digit groups.
This approach is also trivial to extend to higher (or even variable) precision...
@Alexey Frunze 的方法很简单,但非常慢。您应该使用上面 @chill 的 32 位整数方法。另一种无需任何乘法或除法的简单方法是double dabble。这可能比 chill 的算法运行得慢,但比 Alexey 的算法快得多。运行后你会得到一个十进制数的压缩BCD码
@Alexey Frunze's method is easy but it's very slow. You should use @chill's 32-bit integer method above. Another easy method without any multiplication or division is double dabble. This may work slower than chill's algorithm but much faster than Alexey's one. After running you'll have a packed BCD of the decimal number
github 上有一个开源项目 (c++),它提供了数据类型
uint265_t
和uint128_t
的类。https://github.com/calccrypto/uint256_t
不,我不隶属于该项目,但是我将它用于这样的目的,但我想它对其他人也有用。
On github is an open source project (c++) which provides a class for a datatype
uint265_t
anduint128_t
.https://github.com/calccrypto/uint256_t
No, I' not affiliated with that project, but I was using it for such a purpose, but I guess it could be usefull for others as well.