# Big problem : find a number of day.

Discussion in 'Perl Misc' started by Alextophi, Nov 4, 2005.

1. ### AlextophiGuest

*-* 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.

Alextophi, Nov 4, 2005

2. ### Josef MoellersGuest

Alextophi wrote:
> *-* 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;
while (\$day) {
}

HTH,

Josef
--
Josef MÃ¶llers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett

Josef Moellers, Nov 4, 2005

3. ### Anno SiegelGuest

Alextophi <> wrote in comp.lang.perl.misc:
> *-* 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:

}

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

you could also say

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

Rounding the quotient would make it more robust.

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the

Anno Siegel, Nov 4, 2005
4. ### Anno SiegelGuest

V S Rawat <> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
>
> > Alextophi <> wrote in
> > comp.lang.perl.misc:
> > > *-* 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
> > > );

[...]

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

>
> while ( \$day_mask ) {
> print "1", "\$day_array{ \$next ^ \$day_mask}\n";
> print "2 ", log( \$next ^ \$day_mask)/log( 2), "\n";
> }
> exit;
>
> The above gives the output:
> ---------- Capture Output ----------
> > "D:\install\Perl\bin\perl5.8.0.exe" -C Tmp1.pl

> 1
> 2 0
> 1
> 2 1
> 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
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the