将字符串解析为任意进制的整数。

huangapple go评论59阅读模式
英文:

Parse string to integer in arbitrary base/radix

问题

除了Perl之外的其他编程语言,如果我想解析一个以奇怪、非标准进制表示的数字字符串(不一定是正常的二进制(2)、八进制(8)、十进制(10)或十六进制(16)进制),或者基必须在运行时以编程方式确定,将字符串从该进制转换为整数就相当简单,只要进制介于2和36之间(其中大于10的进制使用 a-z 和/或 A-Z 表示更大的数字),例如,要解析以34进制表示的"JQ",得到结果672,我可以这样做:

int("JQ", 34)  # Python
parseInt("JQ", 34);  // JavaScript
strtol("JQ", NULL, 34);     // C或C++,也有strtoul、strtoll、strtoull
std::stol("JQ", NULL, 34);  // 仅限C++,当第一个参数已经是std::string时最佳,与strto*有类似的选项
$((34#JQ))  # 即使bash也可以使用内置功能实现

在Perl中是否有一种内置方法可以进行这种字符串到整数的解析,支持任意进制(最好能在运行时提供),而不依赖于第三方模块,并且不需要我编写大量代码来重复造轮子?(我不希望使用手动循环逐位转换并乘以最终值的任何方法;那样很长、繁琐、容易出错,并且是重复造轮子)

我想,如果答案是“否”,那么至少我可以通过使用反引号或类似的方式让bash为我完成这项工作,但感觉有点奇怪的是,Perl是唯一一种常见的编程语言,包括设计和应用类似的语言(如Ruby、PHP、bash),它缺少这个功能。

英文:

In other languages besides Perl, if I want to parse a string representing a number in a weird, non-standard base (not necessarily the normal binary (2), octal (8), decimal (10), or hexadecimal (16) bases), or the base must be determined programmatically at runtime, converting from string to integer in said base is pretty simple, so long as the base is between 2 and 36 (where bases above 10 use a-z and/or A-Z to represent the larger digits), e.g., to parse "JQ" in base-34, getting 672 as the result, I can do:

int("JQ", 34)  # Python
parseInt("JQ", 34);  // JavaScript
strtol("JQ", NULL, 34);     // C or C++, also strtoul, strtoll, strtoull
std::stol("JQ", NULL, 34);  // C++-only, best when first argument already a std::string, similar options as strto*
$((34#JQ))  # Even bash can do it with built-in functionality

Is there a built-in way to do this string-to-integer parsing, with arbitrary bases (ideally able to be provided at runtime) in Perl that doesn't rely on third-party modules, and doesn't involve me writing a ton of code to reinvent the wheel? (I'm not looking for anything that involves manually looping to convert digit-by-digit and multiply into a final value; that's long, tedious, error-prone, and reinventing the wheel)

I figure if the answer is "No", if nothing else I can cheat by having bash do the work for me with backticks or the like, but it feels kind of weird that Perl, alone among common languages, including languages with similar designs and application (e.g. Ruby, PHP, bash), is missing this functionality.

答案1

得分: 3

以下是翻译好的部分:

"没有理由执行一个 shell 来解析一个任意进制的数字。标准(非第三方)POSIX 模块 提供了 strtol() 函数,与其包装的 C 版本一样,允许您指定介于 2 到 36 之间的进制:

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use POSIX;

say scalar POSIX::strtol("JQ", 34);

需要记住的是,它在列表上下文中返回一个包含两个元素的列表(转换后的数字和不包含在其中的尾随字符的计数),而在标量上下文中只返回转换后的数字。

英文:

There is no reason to execute a shell just to parse a number in an arbitrary base. The standard (Not third-party) POSIX module provides the strtol() function, which, just like the C version it's a wrapper for, lets you specify a base between 2 and 36:

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use POSIX;

say scalar POSIX::strtol("JQ", 34);

The thing that needs remembering so it doesn't cause issues is that it returns a two-element list in list context (The converted number and the count of trailing characters not part of it), and just the converted number in scalar context.

答案2

得分: 0

没有内置方法。

(而且模块推荐,无论是第三方还是其他方式,都是不相关的话题。)

英文:

There is no built-in way.

(And module recommendations, third-party or otherwise, are off-topic.)

huangapple
  • 本文由 发表于 2023年6月9日 01:48:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定