|
| Bit-manipulation og 64 bit tal..... Fra : Ulrik Jensen |
Dato : 12-02-02 18:16 |
|
Hej
Håber der er nogen der kan hjælpe mig med lidt tørt teori.....
Problemet ligger i at jeg vil arbejde med 64-bit tal, som en
repræsentation af 64 - boolske variable, det er altså de forskellige
bits jeg er interesseret i, og ikke de "normale" decimale operationer.
Dette vil mit program dog ikke gøre rigtigt, jeg har prøvet at definere
mine variable på med de to forskellige nedenstående typedefs :
typedef long double bitboard;
typedef __int64 bitboard;
med den første typedef vil den ikke tillade mig at bruge de bitvise
operatorer ( den værende MS VC++ 6.0 ), og med den anden typedef VIRKER
de tilsyneladende ikke ordentligt. Da min forståelse af bitshifting og
lignende ikke var helt perfekt, lavede jeg følgende lille program.
#include "stdio.h"
#include "conio.h"
typedef __int64 bitboard
void main()
{
/* initialiser det første bitboard med bit 30 og 2 sat høj */
bitboard mittal = (1 << 30) | (1 << 2);
/* find alle de høje bits */
for (int i = 0; i < 64; i++)
if (((mittal >> 1) % 2) == 1)
printf("bit %d er on\n", i);
/* lad resultatet stå et sekund */
getch();
}
Dette program virker fint, og outputtet er som forventet :
bit 2 er on
bit 30 er on
MEN hvis jeg ændrer initialiseringen til
bitboard mittal = (1 << 31) | (1 << 2);
Så dør den fuldstændigt, og der kommer intet output.
En anden variation jeg prøvede at lave var at ændre if'en til hvad jeg
mener bør være præcis det samme :
if ((mittal >> 1) % 2)
Med den første initialisering virker dette også fint nok, og giver som
forventet 2 og 30. Men hvis jeg igen ændrer initialiseringen til bit 2
og 31, så reporterer den at bit 2 er on, bit 31 er on, og SAMTLIGE bits
fra 31-64 er OGSÅ tændt....
Er der nogen der kan forklare dette for mig?.... har jeg radikalt
misforstået et eller andet?...
Baggrunden for at jeg skal bruge 64-bit tal er at jeg er ved at lave et
skak-spil, og jeg er kommet frem til via diverse ressourcer om netop
denne type spil, at der kan opnås adskillige (primært hastigheds-)
fordele ved brug af disse såkaldte "bitboards"....
På forhånd tak.
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Kent Friis (12-02-2002)
| Kommentar Fra : Kent Friis |
Dato : 12-02-02 18:27 |
|
Den Tue, 12 Feb 2002 18:15:50 +0100 skrev Ulrik Jensen:
>Hej
>
>Håber der er nogen der kan hjælpe mig med lidt tørt teori.....
>Problemet ligger i at jeg vil arbejde med 64-bit tal, som en
>repræsentation af 64 - boolske variable, det er altså de forskellige
>bits jeg er interesseret i, og ikke de "normale" decimale operationer.
>Dette vil mit program dog ikke gøre rigtigt, jeg har prøvet at definere
>mine variable på med de to forskellige nedenstående typedefs :
>
>typedef long double bitboard;
>typedef __int64 bitboard;
Prøv at bruge en unsigned type (__uint64?) i stedet for. Det kan være
det der forvirrer.
Mvh
Kent
--
8:16pm up 2:37, 1 user, load average: 101.21, 95.46, 55.85
164 processes: 62 sleeping, 102 running, 0 zombie, 0 stopped
With XMMS tugging along nicely, playing Vivaldi...
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 19:40 |
|
Hej
Kent Friis wrote:
> Prøv at bruge en unsigned type (__uint64?) i stedet for. Det kan være
> det der forvirrer.
En tilsvarende unsigned ville jo være 32-bit.... ikke?
et forsøg med
typedef unsigned __int64 BITBOARD
giver samme resultat, og er også en 64-bit værdi, så spørgsmålet er om
den simpelthen ignorerer at jeg ønsker den unsigned?......
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Kent Friis (12-02-2002)
| Kommentar Fra : Kent Friis |
Dato : 12-02-02 20:56 |
|
Den Tue, 12 Feb 2002 19:39:31 +0100 skrev Ulrik Jensen:
>Hej
>
>Kent Friis wrote:
>> Prøv at bruge en unsigned type (__uint64?) i stedet for. Det kan være
>> det der forvirrer.
>
>En tilsvarende unsigned ville jo være 32-bit.... ikke?
>
>et forsøg med
>
>typedef unsigned __int64 BITBOARD
>
>giver samme resultat, og er også en 64-bit værdi, så spørgsmålet er om
>den simpelthen ignorerer at jeg ønsker den unsigned?......
Hvis __int64 er defineret et andet sted som fx:
typedef (signed long long) __int64
så hjælper det vel ikke at sætte unsigned foran? Findes der ikke en
unsigned type du kan bruge?
Mvh
Kent
--
What was your username?
<Clicketyclick> - B.O.F.H.
| |
Bertel Lund Hansen (12-02-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 12-02-02 21:28 |
|
Kent Friis skrev:
>så hjælper det vel ikke at sætte unsigned foran? Findes der ikke en
>unsigned type du kan bruge?
Om ikke andet kan han lave et miniarray. Det giver lidt ekstra
beregning, men til gengæld kan det gøres portabelt. Er den der
__int64 type standard?
--
Bertel
http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 21:42 |
|
Hej
Bertel Lund Hansen wrote:
> Om ikke andet kan han lave et miniarray. Det giver lidt ekstra
> beregning, men til gengæld kan det gøres portabelt. Er den der
> __int64 type standard?
Det tvivler jeg nu på når den har sådan et mærkværdigt navn.... tror
det er noget VC++ har fundet på..... men skal ikke kunne sige det med
sikkerhed.
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Ivan Johansen (12-02-2002)
| Kommentar Fra : Ivan Johansen |
Dato : 12-02-02 21:57 |
|
Ulrik Jensen wrote:
> Hej
> Det tvivler jeg nu på når den har sådan et mærkværdigt navn.... tror
> det er noget VC++ har fundet på..... men skal ikke kunne sige det med
> sikkerhed.
Alt hvad der starter med en eller to underscores er kompilerudvidelser.
Borland kalder for øvrigt også deres 64 bit datatype for __int64.
Ivan Johansen
| |
Martin Moller Peders~ (13-02-2002)
| Kommentar Fra : Martin Moller Peders~ |
Dato : 13-02-02 00:13 |
|
In <Usenet.riajbife@localhost> Ulrik Jensen <ulrik@qcom.dk> writes:
>Hej
>Kent Friis wrote:
>> Prøv at bruge en unsigned type (__uint64?) i stedet for. Det kan være
>> det der forvirrer.
>En tilsvarende unsigned ville jo være 32-bit.... ikke?
>et forsøg med
>typedef unsigned __int64 BITBOARD
>giver samme resultat, og er også en 64-bit værdi, så spørgsmålet er om
>den simpelthen ignorerer at jeg ønsker den unsigned?......
Proev at kigge i sourcen til Crafty, som bruger 64 bitboards.
/Martin
| |
Bertel Lund Hansen (12-02-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 12-02-02 19:11 |
|
Ulrik Jensen skrev:
>typedef long double bitboard;
>...
>med den første typedef vil den ikke tillade mig at bruge de bitvise
>operatorer
Double er en decimaltype (real el. float), så heltalsoperationer
er forbudt.
--
Bertel
http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 19:40 |
|
Hej
Bertel Lund Hansen wrote:
> Double er en decimaltype (real el. float), så heltalsoperationer
> er forbudt.
Ah, ja det er vel egentlig ganske logisk ;)
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Claus Rasmussen (12-02-2002)
| Kommentar Fra : Claus Rasmussen |
Dato : 12-02-02 19:59 |
|
Ulrik Jensen wrote:
> #include "stdio.h"
> #include "conio.h"
>
> typedef __int64 bitboard
>
> void main()
> {
> /* initialiser det første bitboard med bit 30 og 2 sat høj */
> bitboard mittal = (1 << 30) | (1 << 2);
> /* find alle de høje bits */
> for (int i = 0; i < 64; i++)
> if (((mittal >> 1) % 2) == 1)
> printf("bit %d er on\n", i);
>
> /* lad resultatet stå et sekund */
> getch();
> }
>
> Dette program virker fint, og outputtet er som forventet :
>
> bit 2 er on
> bit 30 er on
Det vil jeg tillade mig at tvivle på. Betingelsen i din if-sætning
er et konstant udtryk.
Post lige programmet igen (og uden at pille i det først
-Claus
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 20:42 |
|
Hej
Claus Rasmussen wrote:
> Post lige programmet igen (og uden at pille i det først
Argh du har ret ;) det er skam ikke for at snyde jer for nogle
fabrikshemmeligheder, blot fordi jeg fandt det hurtigere at skrive
programmet over manuelt fra min bærbare til min stationæres newsreader,
end at skulle finde en diskette og så skulle igennem den smøre.....
Der skal selvfølgelig stå
if (((mittal >> i) % 2) == 1)
Hele programmet, denne gang overført digitalt ;)
// skak forsøg
// afprøv at lave bitboards til repræsentation af dataene
#include "stdio.h"
#include "conio.h"
typedef __int64 BITBOARD;
void main()
{
/* initialiser det første bitboard med bit 31 og 2 sat høj */
BITBOARD mittal = (1 << 31) | (1 << 2);
/* find alle de høje bits */
for (int i = 0; i < 64; i++)
if ((mittal >> i) % 2)
{
printf("bit %d er on\n", i);
getch(); /* ikke plads til særligt mange på skærmen af gangen */
}
/* tjek lige størrelsen, just in case */
printf("%d bytes, %d bits", sizeof(BITBOARD), sizeof(BITBOARD)*8);
/* lad resultatet stå et øjeblik */
getch();
}
Resultatet af ovenstående er så "bit 2 er on" og bit 31-63 er on.
Sorry for misforståelsen.
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Claus Rasmussen (13-02-2002)
| Kommentar Fra : Claus Rasmussen |
Dato : 13-02-02 01:06 |
|
Ulrik Jensen wrote:
> #include "stdio.h"
> #include "conio.h"
>
> typedef __int64 BITBOARD;
>
> void main()
> {
> /* initialiser det første bitboard med bit 31 og 2 sat høj */
> BITBOARD mittal = (1 << 31) | (1 << 2);
>
> /* find alle de høje bits */
> for (int i = 0; i < 64; i++)
> if ((mittal >> i) % 2)
> {
> printf("bit %d er on\n", i);
> getch(); /* ikke plads til særligt mange på skærmen af gangen */
> }
>
> /* tjek lige størrelsen, just in case */
> printf("%d bytes, %d bits", sizeof(BITBOARD), sizeof(BITBOARD)*8);
>
> /* lad resultatet stå et øjeblik */
> getch();
> }
>
> Resultatet af ovenstående er så "bit 2 er on" og bit 31-63 er on.
Dit problem er, at når du bruger shift-operatoren, får resultatet
samme type som det, du shifter - dvs. en int i dette tilfælde, da "rå"
tal i et C program er ints. Da en int er signed, og da du sætter den
højeste bit opfattes hele tallet som negativt, og det bliver derfor
sign-extended, når du assigner det til mittal.
Gør i stedet sådan:
mittal = ((unsigned) 1 << 31) | (1 << 2);
(når man blander signed og unsigned bliver resultatet signed, så du
behøves ikke at sætte '(unsigned)' på begge udtryk).
-Claus
| |
Mogens Hansen (12-02-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 12-02-02 20:49 |
|
"Ulrik Jensen" <ulrik@qcom.dk> wrote in message
news:Usenet.sasjccie@localhost...
> #include "stdio.h"
> #include "conio.h"
>
> typedef __int64 bitboard
Der mangler et semikolon.
>
> void main()
main returnerer _altid_ int, hvis det skal være et gyldigt program.
> {
> /* initialiser det første bitboard med bit 30 og 2 sat høj */
> bitboard mittal = (1 << 30) | (1 << 2);
> /* find alle de høje bits */
> for (int i = 0; i < 64; i++)
> if (((mittal >> 1) % 2) == 1)
(mittal >> 1)
giver værdien af "mittal" skiftet een gang til højre. "mittal" ændrer _ikke_
selv værdi. Du får testes om mindst betydende bit er sat 64 gange
Prøv selv at se efter med debuggeren.
> printf("bit %d er on\n", i);
>
> /* lad resultatet stå et sekund */
> getch();
> }
>
> Dette program virker fint, og outputtet er som forventet :
>
Det kan jeg ikke forstå:
* Det compilerer ikke.
* Det tester ikke om alle bit er sat, som forklaret ovenfor.
Der kommer altså ikke noget output.
> bit 2 er on
> bit 30 er on
>
Det er ikke fra det program du har vist.
> MEN hvis jeg ændrer initialiseringen til
>
> bitboard mittal = (1 << 31) | (1 << 2);
>
> Så dør den fuldstændigt, og der kommer intet output.
>
Prøv at trykke en tast - så terminerer programmet.
Det er præcist som før.
> En anden variation jeg prøvede at lave var at ændre if'en til hvad jeg
> mener bør være præcis det samme :
>
> if ((mittal >> 1) % 2)
>
> Med den første initialisering virker dette også fint nok, og giver som
> forventet 2 og 30. Men hvis jeg igen ændrer initialiseringen til bit 2
> og 31, så reporterer den at bit 2 er on, bit 31 er on, og SAMTLIGE bits
> fra 31-64 er OGSÅ tændt....
>
sjovt nok, tror jeg ikke at du observerer på det du fortæller os - så det er
ikke særligt nyttigt.
> Er der nogen der kan forklare dette for mig?.... har jeg radikalt
> misforstået et eller andet?...
>
Husk at når du skriver "1" så er det af typen "int". På Microsoft Visual C++
V6.0 til Win32 på Intel CPU er det en 32 bit størrelse, hvoraf en bit er
fortegn.
Det betyder, at du ikke at du ikke kan skifte den mere end 31 gange, for så
får du undefined behaviour.
Prøv i stedet (læg mærke til castene)
#include "stdio.h"
#include "conio.h"
typedef __int64 bitboard;
int main()
{
/* initialiser det første bitboard med bit 30 og 2 sat høj */
bitboard mittal = ((bitboard) 1 << 42) | ((bitboard) 1 << 30) |
((bitboard) 1 << 2);
/* find alle de høje bits */
for(unsigned i = 0; 64 != i; ++i) {
if(mittal & ((bitboard) 1 << i) ) {
printf("bit %d er on\n", i);
}
}
/* lad resultatet stå et sekund */
getch();
return 0; // to please MSVC 6
}
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (12-02-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 12-02-02 20:58 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:a4brlk$ktj$1@news.cybercity.dk...
>
>
> typedef __int64 bitboard;
>
Det er bedre at bruge
typedef unsigned __int64 bitboard;
i stedet
Venlig hilsen
Mogens Hansen
| |
Byrial Jensen (12-02-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 12-02-02 23:32 |
|
Mogens Hansen <mogens_h@dk-online.dk> skrev:
> "Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
>>
>> typedef __int64 bitboard;
>>
>
> Det er bedre at bruge
>
> typedef unsigned __int64 bitboard;
Og hvis det er et C99-program, er det endnu bedre at bruge
#include <stdint.h>
typedef uint_fast64_t bitboard;
C99 kræver at uint_fast64_t skal eksistere, og at det skal være
en unsigned integer type med mindst 64 bit. Hvis der er flere
typer på 64 bit eller mere at vælge imellem, skal det være den
som det i almindelighed er hurtigst at operere med.
Man kan også bruge uint_least64_t. Den skal også eksistere og er
den mindste unsigned integer type på mindst 64 bit.
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 21:26 |
|
Hej
Mogens Hansen wrote:
> Det er ikke fra det program du har vist.
Nej det var mig der var dum og doven og skrev det manuelt af, der er en
digital overførsel af programmet andetsteds her i tråden ( som svare på
Claus Rasmussens indlæg.
Undskylder meget ulejligheden.
Med hensyn til at det skal være int main() så er det vel en bagatel?
for at det skal være et gyldigt program siger du, men hvilken standard
er det efter, ANSI?.... det virker i hvert fald på mit windows system,
selvom det IKKE skulle undre mig at windows går på kompromis med den
slags. Men du har selvfølgelig ret, der er ingen grund til ikke at gøre
det med en int, men nu laver jeg heldigvis kun konsol-programmer når
jeg lige skal teste nogle småting, så det går nok....
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Bertel Lund Hansen (12-02-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 12-02-02 21:36 |
|
Ulrik Jensen skrev:
>Nej det var mig der var dum og doven og skrev det manuelt af, der er en
>digital overførsel af programmet andetsteds her i tråden
Det bliver det ikke bedre af:
> if (((mittal >> i) % 2) == 1)
Du kan lige så godt skrive enten "if (0)" eller "if (1)". Mittal
bevarer sin værdi, og det er præcis den samme bit der testes hver
gang, nemlig bit 1 (regnet fra 0).
--
Bertel
http://lundhansen.dk/bertel/ FIDUSO: http://fiduso.dk/
| |
Kent Friis (12-02-2002)
| Kommentar Fra : Kent Friis |
Dato : 12-02-02 21:42 |
|
Den Tue, 12 Feb 2002 21:36:09 +0100 skrev Bertel Lund Hansen:
>Ulrik Jensen skrev:
>
>>Nej det var mig der var dum og doven og skrev det manuelt af, der er en
>>digital overførsel af programmet andetsteds her i tråden
>
>Det bliver det ikke bedre af:
>
>> if (((mittal >> i) % 2) == 1)
>
>Du kan lige så godt skrive enten "if (0)" eller "if (1)". Mittal
>bevarer sin værdi, og det er præcis den samme bit der testes hver
>gang, nemlig bit 1 (regnet fra 0).
Huh?
Først skiftes mittal i gange til højre. Derved smides de nederste i
bits væk.
Mvh
Kent
--
Which one is faster - Lotus Notes or Lotus Esprit?
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 22:17 |
|
Hej
Bertel Lund Hansen wrote:
> > if (((mittal >> i) % 2) == 1)
> Du kan lige så godt skrive enten "if (0)" eller "if (1)". Mittal
> bevarer sin værdi, og det er præcis den samme bit der testes hver
> gang, nemlig bit 1 (regnet fra 0).
Med min modulos 2 tester jeg på det første bit, men før jeg gør det
flytter jeg det i'ende bit hen på den første plads, så det er det der
sker. Det er i hvert fald det der er min mening. Om mittal ændrer sig
er vel irrelevant, det er endda nødvendigt, da det er resultatet af (
mittal << i ) jeg tester på, ikke mittal selv.
Men jeg har fået det til at virke, ved hjælp af typecasts ala : if
(mittal & ((bitboard) 1 << i))...; som deet er gjort andetsteds i
tråden.
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Mogens Hansen (12-02-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 12-02-02 21:44 |
|
"Ulrik Jensen" <ulrik@qcom.dk> wrote in message
news:Usenet.ibfrpbgo@localhost...
>
> Med hensyn til at det skal være int main() så er det vel en bagatel?
ja
> for at det skal være et gyldigt program siger du, men hvilken standard
> er det efter, ANSI?
ISO/IEC 9899:1990 (C90)
ISO/IEC 14882:1998 (C++)
som også er en ANSI, DIN, DS etc. vedtaget standard.
og C99 som jeg ikke lige har det præcise navn på her.
> Men du har selvfølgelig ret, der er ingen grund til ikke at gøre
> det med en int, men nu laver jeg heldigvis kun konsol-programmer når
> jeg lige skal teste nogle småting, så det går nok....
>
ja da - men det er sjovt som computere har det med at hænge sig i
bagateller.
Sommetider spiller bagateller en rolle, andre gange ikke. Man kan lige så
godt vænne sig til at lære bagetellerne som en vane - så slipper man for at
overveje om det spiller en rolle i den aktuelle situation.
Venlig hilsen
Mogens Hansen
| |
Ulrik Jensen (12-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 12-02-02 21:31 |
|
Hej
Mogens Hansen wrote:
> if(mittal & ((bitboard) 1 << i) ) {
okay, takker for din hjælp for det første med de casts der, det ser
altsammen ud til at passe, så jeg prøver lige at indføre det i mit
program. Det er også en smartere måde at tjekke bittet, takker!
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Igor V. Rafienko (13-02-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 13-02-02 16:33 |
|
[ Ulrik Jensen ]
[ snip ]
> med den første typedef vil den ikke tillade mig at bruge de bitvise
> operatorer ( den værende MS VC++ 6.0 ),
Det ser ut som de fleste har foreslått en C-aktig løsning der man
begynner å mekke på internrepresentasjonen til en passende "unsigned
integral type" direkte. _Dersom_ du bruker C++, finnes det bedre måter
å gjøre ting på.
[ snip ]
> Baggrunden for at jeg skal bruge 64-bit tal er at jeg er ved at lave
> et skak-spil, og jeg er kommet frem til via diverse ressourcer om
> netop denne type spil, at der kan opnås adskillige (primært
> hastigheds-) fordele ved brug af disse såkaldte "bitboards"....
I utgangspunktet er slik optimalisering ikke nødvendigvis så veldig
lurt: prøv heller å strukturere koden slik at det blir relativt enkelt
å bytte ut sjakkbrettrepresentasjonen og ikke bry deg om slik
mikroeffektivitet i utgangspunktet.
Når det gjelder "bedre måter å gjøre ting på", så tenkte jeg primært
på std::bitset<> (under forutsetning at du skribler i C++). Den
umiddelbare fordelen er at det blir trivielt å migrere vekk fra MVC++.
ivr
--
| |
Ulrik Jensen (13-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 13-02-02 19:04 |
|
Igor V. Rafienko wrote:
> I utgangspunktet er slik optimalisering ikke nødvendigvis så veldig
> lurt: prøv heller å strukturere koden slik at det blir relativt enkelt
> å bytte ut sjakkbrettrepresentasjonen og ikke bry deg om slik
> mikroeffektivitet i utgangspunktet.
Det har jeg gjort, og er snart kommet dertil hvor det er A.I. jeg skal
til at bøvle med, og før jeg går igang med det vil jeg gerne konvertere
skidtet til bitboards.
> Når det gjelder "bedre måter å gjøre ting på", så tenkte jeg primært
> på std::bitset<> (under forutsetning at du skribler i C++). Den
> umiddelbare fordelen er at det blir trivielt å migrere vekk fra MVC++.
Nu er C++ ikke min stærke side, og ting som namespaces, templates og
polymorphing har jeg ikke specielt godt styr på, det jeg skriver er vel
en slags "C+" hvor jeg benytter nogle af fordelene ved C++, men hvor
koden holder sig meget C-style. Desuden er jeg ikke den store tilhænger
af objektorienteret programmering ( dette skriver jeg velvidende at jeg
nu kan risikere at starte en religionskrig ).
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Igor V. Rafienko (13-02-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 13-02-02 22:41 |
|
[ Ulrik Jensen ]
[ snip ]
> Nu er C++ ikke min stærke side, og ting som namespaces, templates og
> polymorphing har jeg ikke specielt godt styr på,
.... hvilket har igrunn ingenting med std::bitset<> å gjøre. Man er
nødt til å ta ibruk ett namespace (std) og en template (bitset). La
meg illustrere:
#include <bitset>
#include <iostream>
#include <sstream>
// [1]
template< typename To, typename From >
To
stream_cast( const From& from ) {
std::stringstream stream;
stream << from;
To to;
stream >> to;
return to;
}
int
main( int argc, char *argv[] )
{
using namespace std;
++argv;
while ( *argv ) {
bitset< 64 > b( stream_cast< unsigned long >( *argv ) );
cout << "number: " << *argv << "\n";
cout << "binary: " << b;
cout << "shifted left by 5: " << (b << 5) << "\n";
cout << "shifted right by 5: " << (b >> 5) << "\n";
cout << "flip all: " << (~b) << "\n";
cout << "bit #3: " << b[3] << "\n";
++argv;
}
}
Pretty damn neat, huh? _Særlig_ med tanke på at dette vil migrere
veldig smidig til 32bits implementasjoner. std::bitset er ment til å
representere effektivt (plass- og tidsmessig) en mendge bit. Bruk det
når du trenger det. Evt. kan man vurdere vector<bool>.
> det jeg skriver er vel en slags "C+" hvor jeg benytter nogle af
> fordelene ved C++, men hvor koden holder sig meget C-style.
Det er selvsagt ditt valg.
ivr
[1] Jeg orker ikke å dille med gazillion forskjellige
konverteringsfunksjoner. stream_cast er så fint, så :)
--
Ehh... I'll have a McRudolf menu, please.
| |
Ulrik Jensen (14-02-2002)
| Kommentar Fra : Ulrik Jensen |
Dato : 14-02-02 00:24 |
|
Hej
Igor V. Rafienko wrote:
[snip]
> while ( *argv ) {
> bitset< 64 > b( stream_cast< unsigned long >( *argv ) );
> cout << "number: " << *argv << "\n";
> cout << "binary: " << b;
> cout << "shifted left by 5: " << (b << 5) << "\n";
> cout << "shifted right by 5: " << (b >> 5) << "\n";
> cout << "flip all: " << (~b) << "\n";
> cout << "bit #3: " << b[3] << "\n";
> ++argv;
[snap]
[snip]
> Pretty damn neat, huh? _Særlig_ med tanke på at dette vil migrere
> veldig smidig til 32bits implementasjoner. std::bitset er ment til å
> representere effektivt (plass- og tidsmessig) en mendge bit. Bruk det
> når du trenger det. Evt. kan man vurdere vector<bool>.
[snap]
Yikes, that IS damn neat..... har jeg forstået det rigtigt at når man
bruger bitset<X> så har man et X-bit tal? det ville være genialt...
Spørgsmålet er jo så, er den ligeså hurtig? for det smarte i bitboards
skulle jo ligge i den opnåelige hastighed, hvormed man kan tjekke
diverse oplysninger på få processor-cycles... men er de bitvise
operationer ligeså hurtige? og hvad med b[3], den svarer vel til at
lave den her (b & (1 << 3) ? ( som jeg har lært efterhånden skal 1 der
dog castes til 64-bit værdier, men stadig ;)
Men smart det er det sq..... tak!
--
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
| |
Igor V. Rafienko (14-02-2002)
| Kommentar Fra : Igor V. Rafienko |
Dato : 14-02-02 12:23 |
|
[ Ulrik Jensen ]
[ snip ]
> Yikes, that IS damn neat..... har jeg forstået det rigtigt at når
> man bruger bitset<X> så har man et X-bit tal? det ville være
> genialt...
Nei, du får ikke et X-bit tall. Du får en _sekvens__ med X bit (det er
vel det du trengte). Du kan, om du ønsker, fiske ut en unsigned long,
dersom X <= sizeof( long ) * CHAR_BIT.
> Spørgsmålet er jo så, er den ligeså hurtig?
Prøv :)
> for det smarte i bitboards skulle jo ligge i den opnåelige
> hastighed, hvormed man kan tjekke diverse oplysninger på få
> processor-cycles... men er de bitvise operationer ligeså hurtige?
Nesten. Det er en array-aksess mer, tenker jeg. Men prøv og se for deg
selv.
> og hvad med b[3], den svarer vel til at lave den her (b & (1 << 3) ?
Ikke helt (man returnerer en proxyklasse). Dog, effekten utad
programmereren er den samme (bortsett fra at med bitset<> kan du
indeksere på den samme måten uansett hvor mange elementer du måtte
ha).
Som jeg foreslo -- lag grensesnittet slik at du kan skifte fritt
mellom unsigned long long, bitset<> og your-homebrew-class. _Dersom_
det viser seg å være nødvendig, kan du lage en spesialrepresentasjon
akkurat for tilfellet ditt (unsigned long long + assert + et par
hjelpefunksjoner).
For Guds skyld, ikke, *ikke*, IKKE putt (b & (1 << 3)) i koden som
jobber med sjakkbrett.
ivr
--
Ehh... I'll have a McRudolf menu, please.
| |
|
|