Big problem : find a number of day.

A

Alextophi

*-* I must find for a number '$day' the day or the days of the table
%day_array:

my $day = 4;
my %day_array = ("1" => "0", # Dimanche
"2" => "1", # Lundi
"4" => "2", # Mardi
"8" => "3", # Mercredi
"16" => "4", # Jeudi
"32" => "5", # Vendredi
"64" => "6" # Samedi
);

my $New_day = $day_array{$day}; # result : $New_day = 2


*-* problem: how to make if $day = 5 or 11 or another ?

5 = 4+1 # result 2 et 0
11 = 8+2+1 # result 3 et 1 et 0


it is a big problem!

thank you

Christophe.
 
J

Josef Moellers

Alextophi said:
*-* I must find for a number '$day' the day or the days of the table
%day_array:

my $day = 4;
my %day_array = ("1" => "0", # Dimanche
"2" => "1", # Lundi
"4" => "2", # Mardi
"8" => "3", # Mercredi
"16" => "4", # Jeudi
"32" => "5", # Vendredi
"64" => "6" # Samedi
);

my $New_day = $day_array{$day}; # result : $New_day = 2


*-* problem: how to make if $day = 5 or 11 or another ?

5 = 4+1 # result 2 et 0
11 = 8+2+1 # result 3 et 1 et 0


it is a big problem!

No, it isn't.
Take a look at Perl's binary operators, specifically the shift, and and
1's complement operators:

my $day=11;
my $mask=1;
while ($day) {
print ' ', $mask if ($day & $mask);
$day &= ~$mask;
$mask <<= 1;
}

HTH,

Josef
 
A

Anno Siegel

Alextophi said:
*-* I must find for a number '$day' the day or the days of the table
%day_array:

my $day = 4;
my %day_array = ("1" => "0", # Dimanche
"2" => "1", # Lundi
"4" => "2", # Mardi
"8" => "3", # Mercredi
"16" => "4", # Jeudi
"32" => "5", # Vendredi
"64" => "6" # Samedi
);

my $New_day = $day_array{$day}; # result : $New_day = 2


*-* problem: how to make if $day = 5 or 11 or another ?

5 = 4+1 # result 2 et 0
11 = 8+2+1 # result 3 et 1 et 0


it is a big problem!

There are straightforward bit-shifting solutions to that. Here is one
that involves a little trick:

my $day_mask = 11;

while ( $day_mask ) {
my $next = $day_mask & ( $day_mask - 1);
print "$day_array{ $next ^ $day_mask}\n";
$day_mask = $next;
}

The expression "$day_mask & ( $day_mask - 1)" deletes (sets to zero)
the least significant bit of $day_mask, leaving the other bits unchanged.
So the XOR of both is the least significant bit in isolation, which is
the index into %day_array.

%day_array isn't even strictly necessary, it is nothing but a coarse
table of logarithms (of base 2). So instead of

print "$day_array{ $next ^ $day_mask}\n";

you could also say

print log( $next ^ $day_mask)/log( 2), "\n";

Rounding the quotient would make it more robust.

Anno
 
A

Anno Siegel

V S Rawat said:
[...]
%day_array isn't even strictly necessary, it is nothing but a
coarse table of logarithms (of base 2). So instead of

print "$day_array{ $next ^ $day_mask}\n";

you could also say

print log( $next ^ $day_mask)/log( 2), "\n";

Rounding the quotient would make it more robust.

Anno

my $day_mask = 11;
while ( $day_mask ) {
print " day_mask: ", $day_mask, "\n";
my $next = $day_mask & ( $day_mask - 1);
print "1", "$day_array{ $next ^ $day_mask}\n";
print "2 ", log( $next ^ $day_mask)/log( 2), "\n";
$day_mask = $next;
}
exit;

The above gives the output:
---------- Capture Output ----------
"D:\install\Perl\bin\perl5.8.0.exe" -C Tmp1.pl
day_mask: 11
1
2 0
day_mask: 10
1
2 1
day_mask: 8
1
2 3
Terminated with exit code 0.

What gives?

Very simple. You have forgotten to provide the hash %day_array with
which to compare the logarithmic calculation. This wouldn't have happened
under strict and warnings.

Anno
 

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

Forum statistics

Threads
474,176
Messages
2,570,949
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top