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
>     }