Bits of a number... why is this true?

N

news.west.cox.net

Forgive my possible ignorance to a seemingly easy question...

Why does this return true?

$num = 24465973248
if ($num & 131072) {
do something...
}

The 18th bit of the binary representation of $num is off.
 
U

Uri Guttman

nwcn> Forgive my possible ignorance to a seemingly easy question...
nwcn> Why does this return true?

nwcn> $num = 24465973248
nwcn> if ($num & 131072) {
nwcn> do something...
nwcn> }

nwcn> The 18th bit of the binary representation of $num is off.

and what is the binary representation of that number? how many bits can
you store in a perl number? do you know the difference between integers
and floating point representations?

uri
 
N

news.west.cox.net

and what is the binary representation of that number? how many bits can
you store in a perl number? do you know the difference between integers
and floating point representations?

uri

Below is binary for 24465973248
10110110010010010010010000000000000
100000000000000000
Above is binay for 131072

I do not know how many bits can go in a perl number. I tried to goole for
the answer, but couldn't come up with anything.

integers are whole numbers and floating point are decimal numbers???

Thanks for any help.
 
N

news.west.cox.net

Herb Martin said:
A hint (but I don't know without further investigation) is
that most current machines/languages limit the size of an
integer to 32 bits (4 GB or 2GB with negatives).

While this number 24465973248, or 24,465,973,248
is 24 billion -- quite bit (sorry) larger than the likely
4 GB limit.

Chances are it is stored as either a float or some other
special representation.

The answer might also be in someway related to positive
and negative representations and such conversions to
different bit widths during the comparison.

I understand what you are saying. But, is there a way that I
can still accomplish my original goal.

I have 35 items, each of which I assign a number... like
1, 2, 4, 8, 16, 32, .... ,17179869184

2**0 = 1
2**34 = 17179869184

So there are 35 numbers. After all options are decided the
numbers are added up and saved to a database.

I now want to retrieve the number and see what bits are on.
So I do something like:

sub getBit {
$number = shift;
$bit = shift;
if ($number & $bit) {
do something
}
}

Actually my subroutine is more complex and is called recursivly
to find all bits. But, how can I do this with numbers > 32 bit?

Thanks
 
U

Uri Guttman

nwcn> I understand what you are saying. But, is there a way that I
nwcn> can still accomplish my original goal.

even so, you should learn more about binary representation.

as for how many bits in a perl number, that is trivial to find and you
don't need google. try perl -v

nwcn> I have 35 items, each of which I assign a number... like
nwcn> 1, 2, 4, 8, 16, 32, .... ,17179869184

bah! first off, if you are going to use bit fields, DON'T USE DECIMAL
VALUES!! use hex (0x) octal or even binary (0b). perl supports them all.

nwcn> 2**0 = 1
nwcn> 2**34 = 17179869184

duh! we know what bit fields are.

nwcn> So there are 35 numbers. After all options are decided the
nwcn> numbers are added up and saved to a database.

gack. that is a horrible design, adding bit fields and assuming they
will all fit into whatever you have. what about the DB? what binary
format and size will it have? you are just compounding your problem there.

nwcn> I now want to retrieve the number and see what bits are on.
nwcn> So I do something like:

nwcn> sub getBit {
nwcn> $number = shift;
nwcn> $bit = shift;
nwcn> if ($number & $bit) {
nwcn> do something
nwcn> }
nwcn> }

print 'gack!' x 2 ;

perldoc -f vec

and look at Bit::Vector on cpan.

nwcn> Actually my subroutine is more complex and is called recursivly
nwcn> to find all bits. But, how can I do this with numbers > 32 bit?

i would suggest you specify the real problem. i smell XY here. you are
trying to find a solution using X (in this case bit fields and poorly
understood at that) and you really want to solve something else but
haven't told us.

uri
 
T

Tad McClellan

I understand what you are saying. But, is there a way that I
can still accomplish my original goal.


Yes, but a much much better solution would be to choose
a less absurd data structure...

I have 35 items, each of which I assign a number... like
1, 2, 4, 8, 16, 32, .... ,17179869184
I now want to retrieve the number and see what bits are on.


-----------------
sub bits_are_set {
my($num) = @_;
my @bits; # the bits that are set

foreach my $exponent ( reverse 0 .. 34 ) {
next if $num < 2 ** $exponent;
push @bits, $exponent;
$num -= 2 ** $exponent;
}
return @bits;
}
-----------------

But, how can I do this with numbers > 32 bit?


You should seriously consider using a hash to represent your
set rather than using a bit vector.
 
T

Tad McClellan

Uri Guttman said:
bah! first off, if you are going to use bit fields, DON'T USE DECIMAL ^^^^^^^^^^^^^^^^^
VALUES!!
^^^^^^

Your shift key doesn't work, but your caps lock key does?

You need to upgrade your keyboard man...

use hex (0x) octal or even binary (0b). perl supports them all.


Bah! Ignore Uri this time.

0x0A hex
10 decimal
012 octal
1010 binary

Those are all *the same* value, just different representations
for that value.

Uri must have meant "don't use decimal representations" instead.
 
U

Uri Guttman

TM> ^^^^^^

TM> Your shift key doesn't work, but your caps lock key does?

TM> You need to upgrade your keyboard man...

i never use caps lock. i just lean on shift when i yell :).


TM> Bah! Ignore Uri this time.

ignore me all the time, please!

TM> 0x0A hex
TM> 10 decimal
TM> 012 octal
TM> 1010 binary

TM> Those are all *the same* value, just different representations
TM> for that value.

TM> Uri must have meant "don't use decimal representations" instead.

yeah. just seeing decimals used for large binary flags is so fugly.

uri
 
S

Sisyphus

news.west.cox.net said:
Forgive my possible ignorance to a seemingly easy question...

Why does this return true?

$num = 24465973248
if ($num & 131072) {
do something...
}

The 18th bit of the binary representation of $num is off.

Fwiw the following will work for numbers of *any* size - limited only by
your machine's memory capabilities.

use warnings;
use Math::BigInt;

my $x = Math::BigInt->new('24465973248');
my $y = Math::BigInt->new('131072');

print $x & $y, "\n";

__END__

For really big numbers you would switch to using Math::GMP, or
Math::pARI, or Bit::Vector - as Math::BigInt becomes a little slow.

Cheers,
Rob
 
J

Joe Smith

news.west.cox.net said:
I do not know how many bits can go in a perl number.

You should do some simple tests to find the number of bits
for the particular version of perl you are using.

linux% cat test.pl
$num = 24465973248;
$bit18 = 131072;
printf "%15.2f = 0x%09x = 0xb%036b\n",$_,$_,$_ for
($num,$bit18,$num&$bit18);
linux% perl test.pl
24465973248.00 = 0x0ffffffff = 0xb000011111111111111111111111111111111
131072.00 = 0x000020000 = 0xb000000000000000000100000000000000000
131072.00 = 0x000020000 = 0xb000000000000000000100000000000000000

Now try it on a system using a CPU that is wider than 32 bits.

tops20@ type test.pl
$num = 24465973248;
$bit18 = 131072;
for ($num, $bit18, $num&$bit18) {
printf "%15.2f = 0x%09x = 0xb%036b\n",$_,$_,$_ ;
}
tops20@ perl test.pl
24465973248.00 = 0x5b2492000 = 0xb(printf: 'b'?)
131072.00 = 0x000020000 = 0xb(printf: 'b'?)
0.00 = 0x000000000 = 0xb(printf: 'b'?)

-Joe
 
P

Peter Scott

nwcn> I understand what you are saying. But, is there a way that I
nwcn> can still accomplish my original goal.

even so, you should learn more about binary representation.

as for how many bits in a perl number, that is trivial to find and you
don't need google. try perl -v

Sometimes you need to use the shift key :) For the benefit of
anyone who couldn't tell, that should be perl -V.
 
T

Ted Zlatanov

I have 35 items, each of which I assign a number... like
1, 2, 4, 8, 16, 32, .... ,17179869184

2**0 = 1
2**34 = 17179869184

So there are 35 numbers. After all options are decided the
numbers are added up and saved to a database.

I now want to retrieve the number and see what bits are on.

You may want to consider an inversion list. It has many advantages
over bit vectors, especially if you expect few options to be turned on
in your bit vector. Check this article out:

http://www-106.ibm.com/developerworks/linux/library/l-cpinv.html

Good luck
Ted
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top