Re: [Boston.pm] converting a thing to a number
email-2Ro/Dj86MvDSUeElwK9/[email protected] Wed, 23 Feb 2022 08:31:12 -0600
| Newsgroups | gmane.comp.lang.perl.perl-mongers.boston |
|---|---|
| Message-ID | <[email protected]> |
Copy/pasting a regexp for checking
would probably work in my situation.
That numpack idea is great.
It solves another issue i didnt
even mention which is that some
numbers can be arbitrarily huge.
If i parse one char at a time,
I should be able to use bignum
and still get the correct answer.
A little surprised there isnt a
way to restrict eval to some
particular perl grammar subrule like
"Numeric literal". (Shrug)
Regexps will be a bit more work
but will do the job.
Thanks everyone!
Greg
On 2022-02-22 22:01, Jerrad Pierce wrote:
> There are two things you can do:
>
> a) use regular expressions on the "numbers" to see if they conform
> to known format, and then eval iff they do; you can then bypass eval
> for integer/float since +0 will cover it.
>
> e.g; e.g; /\s+0b[01]+\s+/
>
> You should be able to crib RE from RegExp::Common, no need to install
> and use the full module.
>
> b) use regular expressions to identify the format plus some packing/
> unpacking and code-point indexing to convert the number without eval:
>
> # binary 285, this implementation is sensitive to leading zeroes--
> # others may not be--and requires whole bytes. Padding is left as
> # an exercise for the reader
> $num = numpack("B*", "0000000100011101");
>
> #hex 3735928559
> $num = numpack("H*", "deadbeef")
>
> sub numpack {
> my($fmt, $val)=@_;
> my($i, $sum)=(1, 0);
>
> my @char =split //, unpack("a*", pack($fmt, $val));
> my $bytes=scalar(@char);
> foreach(@char){ $sum+=ord()<<(8*($bytes-$i++))}; #shift and add bytes
> return $sum
> }