将数字转换为字符串并返回

发布于 2024-09-15 18:58:57 字数 463 浏览 6 评论 0原文

我一直使用流、printf、string(x) 或任何相关语言提供的将数字类型转换为字符串或返回的语言。然而我从来没有真正考虑过这是如何实际完成的。我在谷歌上搜索了一下,但所有的结果只是使用这些不同的方法,而不是在幕后真正完成转换的:(

对于使用二进制、八进制和十六进制的整数似乎相当简单,因为每个“数字”中的“数字” string 表示一组位(例如,对于 2 个十六进制数字,我知道它的 xxxxyyyy),因此我可以通过位移位并一次取一个数字来实现,例如,对于十六进制字符串 0xFA20,值是“(15 < < 12) | (10 << 8) | (2 << 4) | (0 << 0)"。

十进制整数更难,因为基数 10 不会像这样映射到基数 2因此,一位可能会影响多个十进制数字,从而使转换变得更加复杂...

至于浮点数,我真的不知道可以将整数部分和小数部分分开考虑还是指数? 、一组有效数字或一组小数位数?

I have always used streams, printf, string(x) or whatever the language in question offered to convert numeric types to a string or back. However I have never really considered how this is actually done. I searched around on Google, but all the results are just to use those varies methods, and not how the conversion is really done behind the scenes :(

For integers using binary, octal and hexadecimal seems fairly straight forward since each "digit" in the string represents a set group of bits (eg for the 2 hex digits I know its xxxxyyyy), so I could do it with bit shifts and taking one digit at a time, eg for the hex string 0xFA20 the value is "(15 << 12) | (10 << 8) | (2 << 4) | (0 << 0)".

Decimal integers are more difficult since base 10 doesn't map to base 2 like that and so one bit may effect more than one decimal digit making conversion both ways more complex...

As for floating point numbers I really have no idea. I guess the whole and fractional parts could be considered separately or something? What about as an exponential, a set number of significant figures or set number of decimal places?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧夏天 2024-09-22 18:58:57

十进制转换有点慢,但实际上并没有复杂得多。让我们看看十六进制转换,就像我们可能用实际代码编写的那样。举例来说,在 C++ 中,您可能会进行如下转换:

char digits[] = "0123456789abcdef";
std::string result;

int input = 0xFA20;

while (input) {
    int digit = input & 0xf; // or: digit = input % 0xf;
    input >>= 4;             // or: input /= 16;
    result.push_front(digits[digit]);
}

然而,现在有一些神奇的数字。让我们摆脱它们:

const int base = 16;

while (input) { 
    int digit = input % (base - 1);
    input /= base;
    result.push_front(digits[digit]);
}

在摆脱这些神奇数字的过程中,我们还使例程几乎通用 - 如果我们更改“base”的值,例程的其余部分仍然有效,并转换输入到指定的基地。本质上,如果我们想要支持大于 16 的基数,我们需要做的唯一其他更改是向“digits”数组添加更多内容。

为了简单起见,这也忽略了一些事情。最明显的是,如果数字为负数,通常会设置一个标志,转换为正数,最后如果设置了标志,则在字符串中放入“-”)。对于 2 的补码,存在最大负数的极端情况,无法将其转换为正数(无需转换为具有更大范围的类型)。通常,您可以通过推广大多数类型来解决这个问题。对于最大的整数类型(无法升级),通常最简单的方法是硬编码该值。

原则上,浮点并没有太大的不同——你基本上仍然进行数学运算来一次生成一位数字。事实上,它变得更加复杂,因为您通常必须处理几种不同的格式(至少是“基本”浮点和某种“科学”格式)以及字段宽度和精度的变量。当你处理完这个问题时,你最终会得到几百行左右的代码——这并不是一个特别离谱的数量,但可能比包含在这里有意义的多了一点。

Decimal conversions are a bit slower, but not really a lot more complex. Let's look at the hexadecimal conversion a bit more like we'd probably write it in real code. Just for example, in C++ you might do the conversion something like this:

char digits[] = "0123456789abcdef";
std::string result;

int input = 0xFA20;

while (input) {
    int digit = input & 0xf; // or: digit = input % 0xf;
    input >>= 4;             // or: input /= 16;
    result.push_front(digits[digit]);
}

Right now, however, that has some magic numbers. Let's get rid of them:

const int base = 16;

while (input) { 
    int digit = input % (base - 1);
    input /= base;
    result.push_front(digits[digit]);
}

In the process of getting rid of those magic numbers, we've also made the routine nearly universal -- if we change the value of 'base', the rest of the routine still works, and converts the input to the specified base. Essentially the only other change we need to make is adding more to the "digits" array if we want to support bases larger than 16.

This also ignores a few things for simplicity. Most obviously, if the number is negative, you typically set a flag, convert to a positive number, and at the end if the flag was set, put a '-' into the string). With 2's complement there's a corner case for the maximally negative number, which can't be converted to a positive number (without converting to a type with more range). Typically you deal with that by promoting most types. For your largest integer type (which you can't promote) it's usually easiest to just hard-code that one value.

In principle floating point isn't a whole lot different -- you still basically do mathematical manipulations to generate one digit at a time. In fact, it gets more complex simply because you typically have to deal with a couple of different formats (at least a "basic" floating point and some sort of "Scientific" format), as well as variables for field width and precision. By the time you've dealt with that, you end up with a few hundred lines of code or so -- not a particularly outrageous amount, but probably a bit more than makes sense to include here.

谁的年少不轻狂 2024-09-22 18:58:57

我在 Google 上进行了搜索,但所有结果都只是使用这些不同的方法,而不是在幕后真正完成转换的:(

出于性能原因,从一种表示转换为另一种表示(特别是浮点/整数转换)通常是低级 CPU 指令,并且在处理器级别实现,这就是为什么您通常不会在库或语言级别重新实现它,

这在信号处理领域尤其常见 。您想要获取波形并将其转换为某个范围内的离散整数值。

I searched around on Google, but all the results are just to use those varies methods, and not how the conversion is really done behind the scenes :(

For performance reasons, converting from one representation to another (particularly floating-point/integer conversions) is often a low-level CPU instruction and is implemented at the processor level. That's why you don't typically see it re-implemented in libraries or at a language level.

This is especially common in the signal-processing world, for example, where you want to take a waveform and convert it into a discrete integer value in some range.

肥爪爪 2024-09-22 18:58:57

对于整数,您可以找到除法余数,这是最后一位数字,除以 10,找到模余数 - 这是最后一位数字,依此类推。
浮点数由两部分组成 - 有效数字和指数,即
number = important.digits * (base ^ exponent),其中 base 可以是 10、2 或其他数字。

For integers you can find division remainder, this is last digit, divide by 10, found modular residual - this is one but last digit, and so on.
Floating point numbers are constructed of two parts - significant digits and exponent, i.e.
number = significant.digits * (base ^ exponent), where base can be 10, 2, or other number.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文