无符号整数到 BCD 的转换?
我知道您可以使用此表将十进制转换为 BCD:
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
是否有此转换的方程式,或者您只需使用该表?我试图为此转换编写一些代码,但我不确定如何计算它。建议?
I know you can use this table to convert decimal to BCD:
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
Is there a equation for this conversion or you have to just use the table? Im trying to write some code for this conversion but Im not sure how to do the math for it. Suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
您知道二进制数字系统,不是吗?
特别要看看本章。
编辑:另请注意 KFro 的评论,即数字的二进制 ASCII 表示形式的低半字节(= 4 位)采用 BCD 格式。这使得 BCD <-> 转换变得容易。 ASCII 非常简单,因为您只需添加/删除前 4 位:
You know the Binary numeral system, don't you?
Especially have a look at this chapter.
EDIT: Also note KFro's comment that the lower nibble (= 4 bits) of the binary ASCII representation of numerals is in BCD. This makes conversions BCD <-> ASCII very easy as you just have to add/remove the leading 4 bits:
这是来自微控制器世界......请注意,除法中的值是四舍五入的。例如,91 转换为 BCD 为 91/10 * 16 = 144 + 91%10 = 145。转换为二进制为 10010001。
This is from the micro controller world.... Note that values are rounded in the division. For instance 91 to BCD would be 91/10 * 16 = 144 + 91%10 = 145. Converted to Binary is 10010001.
通常,当有人说他们想要从十进制转换为 BCD 时,他们指的是不止一位十进制数字。
BCD 通常被打包为每个字节两位十进制数字(因为 0..9 适合 4 位,如您所示),但我认为使用字节数组(每个十进制数字一个)更自然。
n 位无符号二进制数将适合 ceil(n*log_2(10)) = ceil(n/log10(2)) 个十进制数字。它也适合 ceil(n/3) = Floor((n+2)/3)) 小数位数,因为 2^3=8 小于 10。
考虑到这一点,以下是我获得小数的方法无符号 int 的位数:
当然,如果您知道 int 类型的宽度,您可能更喜欢固定长度数组。如果您还记得第 0 位是最不重要的数字并且仅在输入/输出上反转,则根本没有理由反转。在不使用固定位数的情况下,将最低有效数字保留为第一位可以简化数字算术运算。
如果您想将“0”表示为单个“0”十进制数字而不是空数字字符串(两者都有效),那么您需要专门检查 x==0。
Usually when someone says they want to convert from decimal to BCD, they're talking about more than one decimal digit.
BCD is often packed into two decimal digits per byte (because 0..9 fit in 4 bits, as you've shown), but I think it's more natural to use an array of bytes, one per decimal digit.
An n-bit unsigned binary number will fit into ceil(n*log_2(10)) = ceil(n/log10(2)) decimal digits. It will also fit in ceil(n/3) = floor((n+2)/3)) decimal digits, since 2^3=8 is less than 10.
With that in mind, here's how I'd get the decimal digits of an unsigned int:
Of course, if you know the width of your int type, you may prefer fixed length arrays. There's also no reason to reverse at all if you can remember the fact that the 0th digit is the least significant and reverse only on input/output. Keeping the least significant digit as the first simplifies digit-wise arithmetic ops in the case that you don't use a fixed number of digits.
If you want to represent "0" as the single "0" decimal digit rather than the empty digit-string (either is valid), then you'd check specifically for x==0.
如果您希望每个字节有两个十进制数字,并且“unsigned”是“unsigned long”大小的一半(如果需要,请使用 uint32 和 uint64 typedef):
这会在最低有效一半中留下最低有效(单位)十进制数字-字节。您还可以执行循环固定次数(对于 uint32 为 10)次,而不是在仅剩下 0 位时提前停止,这将允许优化器展开它,但如果您的数字通常很慢,则速度会更慢。
If you want two decimal digits per byte, and "unsigned" is half the size of "unsigned long" (use uint32 and uint64 typedefs if you want):
This leaves you with the least significant (unit) decimal digit in the least significant half-byte. You can also execute the loop a fixed number (10 for uint32) of times, not stopping early when only 0 bits are left, which would allow the optimizer to unroll it, but that's slower if your numbers are often slow.
这样的事情对你的转变有用吗?
Would something like this work for your conversion?
该代码进行编码和解码。基准如下。
我在这里使用了 uint64_t 来存储 BCD。非常方便且宽度固定,但对于大桌子来说空间利用率不高。将 BCD 数字 2 打包到 char[] 中。
注意:
看起来,即使对于 64 位整数,左移超过 32 位也是不可能的,但幸运的是,完全可以乘以 16 的某个因数 - 这很高兴地达到了预期的效果。它也快得多。去算算吧。
This code encodes and decodes. Benchmarks are as follows.
I used an uint64_t to store the BCD here. Very convenient and fixed width, but not very space efficient for large tables. Pack the BCD digits, 2 to char[] for that.
NOTE:
It appears that it's impossible, even with 64-bit ints, to shift left more than 32 bits, but fortunately, it's entirely possible to multiply by some factor of 16 - which happily has the desired effect. It's also much faster. Go figure.
我知道之前已经回答过这个问题,但我已经使用模板将其扩展为不同大小的无符号整数来构建特定代码。
I know this has been previously answered but I've extended this for unsigned ints of different sizes using a template to build the specific code.
这是 uint16_t 的宏,以便在编译时对其进行评估(假设 u 是预定义的常量)。这与上面的 dec2bcd() 一致,直到 9999。
Here is a macro for uint16_t, so that it gets evaluated at compile-time (provided that u is a pre-defined constant). This agrees with dec2bcd() from above up to 9999.
只是简化了而已。
Just simplified it.