/ Forside / Teknologi / Udvikling / VB/Basic / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
VB/Basic
#NavnPoint
berpox 2425
pete 1435
CADmageren 1251
gibson 1230
Phylock 887
gandalf 836
AntonV 790
strarup 750
Benjamin... 700
10  tom.kise 610
Bit operationer i VB
Fra : Flemming Klug


Dato : 10-04-01 13:39

Hej.

Jeg leder forgæves efter kommandoer som SHR og SHL i Visual Basic. Er der
nogen der ved hvad de hedder, eller hvad man kan gøre i stedet.

På forhånd tak

--
Med venlig hilsen

Flemming Klug
fklug@xxxmail.dk




 
 
Thomas J. (10-04-2001)
Kommentar
Fra : Thomas J.


Dato : 10-04-01 17:16

Hej
Jeg har selv prøve at finde dem. Jeg tror ikke de findes
(Bruger VB5)

Med venlig hilsen
Thomas

"Flemming Klug" <fklug@mail.dk> skrev i en meddelelse
news:9auv9n$h1n$1@news.inet.tele.dk...
> Hej.
>
> Jeg leder forgæves efter kommandoer som SHR og SHL i Visual Basic. Er der
> nogen der ved hvad de hedder, eller hvad man kan gøre i stedet.
>
> På forhånd tak
>
> --
> Med venlig hilsen
>
> Flemming Klug
> fklug@xxxmail.dk
>
>
>



Morten Fast (10-04-2001)
Kommentar
Fra : Morten Fast


Dato : 10-04-01 19:14


"Flemming Klug" <fklug@mail.dk> wrote in message
news:9auv9n$h1n$1@news.inet.tele.dk...
> Jeg leder forgæves efter kommandoer som SHR og SHL i Visual Basic. Er der
> nogen der ved hvad de hedder, eller hvad man kan gøre i stedet.

Det er simplere end man tror:

Shift Right = divider med 2
Shift Left = multiplicer med 2

Binær og/eller hedder i VB det samme som logisk og/eller,
nemlig And og Or.

--
Vh Morten



Thomas J. (10-04-2001)
Kommentar
Fra : Thomas J.


Dato : 10-04-01 21:26


"Morten Fast" <usenet@freestate.dk> skrev i en meddelelse
news:9aviio$lov$1@news.inet.tele.dk...
>
> "Flemming Klug" <fklug@mail.dk> wrote in message
> news:9auv9n$h1n$1@news.inet.tele.dk...
> > Jeg leder forgæves efter kommandoer som SHR og SHL i Visual Basic. Er
der
> > nogen der ved hvad de hedder, eller hvad man kan gøre i stedet.
>
> Det er simplere end man tror:
>
> Shift Right = divider med 2
> Shift Left = multiplicer med 2
>
> Binær og/eller hedder i VB det samme som logisk og/eller,
> nemlig And og Or.
>
> --
> Vh Morten
>
>
Kunne det ikke resultere i en "overflow"? f.eks.:

dim myLong as long
myLong = &HFFFFFFFF
myLong = myLong * 2 ' "overflow", myLong vil stadig være &HFFFFFFFF.

Nogen løsning ?

Med venlig hilsen
Thomas




Tomas Christiansen (10-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 10-04-01 21:59

Thomas J. skrev:
> Kunne det ikke resultere i en "overflow"? f.eks.:
>
> dim myLong as long
> myLong = &HFFFFFFFF
> myLong = myLong * 2 ' "overflow", myLong vil stadig være &HFFFFFFFF.

Det var blot én af mange muligheder for overflow!

Her er et workaround - bemærk at jeg bruger + i stedet for * idet det burde
gå lidt hurtigere...

Function SHL(ByVal X As Long) As Long
SHL = (X And &H3FFFFFFF) + (X And &H3FFFFFFF)
If (X And &H40000000) <> 0 Then
SHL = SHL Or &H80000000
End If
End Function

-------
Tomas



Tomas Christiansen (10-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 10-04-01 22:04

Tomas Christiansen skrev:
> Her er et workaround - bemærk at jeg bruger + i stedet for * idet det
burde
> gå lidt hurtigere...

Okay, der kommer også lige en version med * i stedet for +

Function SHL(X As Long) As Long
If lng And &H40000000 Then
SHL = (X And &H3FFFFFFF) * 2 Or &H80000000
Else
SHL = (X And &H7FFFFFFF) * 2
End If
End Function

-------
Tomas



Morten Fast (11-04-2001)
Kommentar
Fra : Morten Fast


Dato : 11-04-01 17:12


"Thomas J." <pppp@europe.com> wrote in message
news:9avq7g$n4n$1@news.inet.tele.dk...
> Kunne det ikke resultere i en "overflow"?
> Nogen løsning ?

Problemet med overflow vil kun opstå i forbindelse med Shift Left.

Tomas har givet et par eksempler på hvordan Shift Left kan løses,
men det kan gøres endnu kortere. Du fjerner blot den øverste bit:

Function ShiftLeft(Tal As Long) As Long

ShiftLeft = (Tal And &H80000000) * 2

End Function

--
Vh Morten



Morten Fast (11-04-2001)
Kommentar
Fra : Morten Fast


Dato : 11-04-01 17:43


"Morten Fast" <usenet@freestate.dk> wrote in message
news:9b1vr4$ici$1@news.inet.tele.dk...

Doh! Jeg regnede lige forkert... Det skal selvfølgelig være:

Function ShiftLeft(Tal As Long) As Long
ShiftLeft = (Tal And &H7FFFFFFF) * 2
End Function

--
Vh Morten



Tomas Christiansen (11-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 11-04-01 23:49

Morten Fast skrev:
> Tomas har givet et par eksempler på hvordan Shift Left kan løses,
> men det kan gøres endnu kortere. Du fjerner blot den øverste bit:
....
> Function ShiftLeft(Tal As Long) As Long
> ShiftLeft = (Tal And &H7FFFFFFF) * 2
> End Function

Tror du at det er for sjov at jeg skriver meget kode?

Det er da skam en ret god grund til, prøv selv at "fodre" din rutine med tal
hvor den næst-øverste bit er sat, og du vil forstå hvorfor:

Debug.Print ShiftLeft(&H4FFFFFFF)
Debug.Print ShiftLeft(&H5FFFFFFF)
Debug.Print ShiftLeft(&H6FFFFFFF)
Debug.Print ShiftLeft(&H7FFFFFFF)
Debug.Print ShiftLeft(&HCFFFFFFF)
Debug.Print ShiftLeft(&HDFFFFFFF)
Debug.Print ShiftLeft(&HEFFFFFFF)
Debug.Print ShiftLeft(&HFFFFFFFF)

-------
Tomas



Morten Fast (12-04-2001)
Kommentar
Fra : Morten Fast


Dato : 12-04-01 09:47


"Tomas Christiansen" <toc@blikroer.removethis.dk> wrote in message
news:vb5B6.562$4%2.15397@news.get2net.dk...

> Tror du at det er for sjov at jeg skriver meget kode?

Er det ikke det, der er meningen med at skrive kode?


> Det er da skam en ret god grund til, prøv selv at "fodre" din rutine
> med tal hvor den næst-øverste bit er sat, og du vil forstå hvorfor:

VB kan ikke - med undtagelse af typen Byte - bruge unsigned
talvariabler, og det tog min funktion ganske rigtigt ikke højde for.

Det er nemlig en rigtig dårlig ide, at shifte signed variabler,
men bare for syns skyld, så kommer her en funktion, der både bruger
signed variabler og rent faktisk virker (med mindre man sender den
værdien &H80000000, hvilket er en af grundene til, at man ikke bør
shifte signed variabler):

Function ShiftLeft(Tal As Long) As Long

If (Tal And &H80000000) Then
ShiftLeft = (Not (ShiftLeft(Not (Tal - 1)))) + 1
Else
ShiftLeft = (Tal And &H3FFFFFFF) * 2
End If

End Function

--
Vh Morten



Tomas Christiansen (12-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 12-04-01 22:48

Morten Fast skrev:
> Er det ikke det, der er meningen med at skrive kode?

Nå, jo!

> Det er nemlig en rigtig dårlig ide, at shifte signed variabler,

Øh - bø. Hvorfor det?
Når man foretage binære venstre- eller højreskift må da vel være fordi at
man er interesseret i at kigge på bittene i den pågældende variabel, og man
kan derfor være ganske ligeglad med hvilken værdi VB måtte tolke det som. At
en værdi skifter fortegn er vel fløjtende ligegyldig, når bare det handler
om bit?

> men bare for syns skyld, så kommer her en funktion, der både bruger
> signed variabler og rent faktisk virker (med mindre man sender den
> værdien &H80000000

Den virker, ja, men kommer blot ikke altid til det rigtige resultat.
Prøv med ShiftLeft(&H7FFFFFFF) og ShiftLeft(&H80000001).

-------
Tomas



Morten Fast (13-04-2001)
Kommentar
Fra : Morten Fast


Dato : 13-04-01 00:11


"Tomas Christiansen" <toc@blikroer.removethis.dk> wrote in message
news:FppB6.388$6X3.8797@news.get2net.dk...

> > Det er nemlig en rigtig dårlig ide, at shifte signed variabler,
> Øh - bø. Hvorfor det?

Fordi resultatet ikke bliver, som man skulle vente.
Et hurtigt lille 8-bit signed-eksempel:
Tallet -104 (1001 1000) skal shiftes en bit til venstre.
Resultat: 1100 1100
Hvis det havde været unsigned, så havde resultatet været et
helt andet (og det man skulle forvente), nemlig 0011 0000.

> Når man foretage binære venstre- eller højreskift må da vel
> være fordi at man er interesseret i at kigge på bittene i
> den pågældende variabel, og man kan derfor være ganske ligeglad
> med hvilken værdi VB måtte tolke det som.

Nej, kun ved unsigned variabler, eller positive værdier
i signed variabler, jvf. eksemplet ovenfor.

> At en værdi skifter fortegn er vel fløjtende ligegyldig,
> når bare det handler om bit?

Nej, for bitrækken laves om, når du shifter negative signed
datatyper.

> Den virker, ja, men kommer blot ikke altid til det rigtige resultat.
> Prøv med ShiftLeft(&H7FFFFFFF) og ShiftLeft(&H80000001).

Hvis jeg prøver med &H7FFFFFFF så får jeg &H7FFFFFFE,
ganske som jeg burde ved signed datatyper:

&H7FFFFFFF = 0111 1111 1111 1111 1111 1111 1111 1111
&H7FFFFFFE = 0111 1111 1111 1111 1111 1111 1111 1110

Hvis jeg prøver med &H80000001 så får jeg &H80000002:

&H80000001 = 1000 0000 0000 0000 0000 0000 0000 0001
&H80000002 = 1000 0000 0000 0000 0000 0000 0000 0010

Husk at den øverste bit afgør om tallet er positivt eller
negativt. Den bliver ikke flyttet med.
Tallet er reelt kun 31 bit stort.

Funktionen både virker og regner rigtigt.

--
Vh Morten



Morten Fast (13-04-2001)
Kommentar
Fra : Morten Fast


Dato : 13-04-01 00:17


"Morten Fast" <usenet@freestate.dk> wrote in message
news:9b5cp6$pn9$1@news.inet.tele.dk...

Nu er jeg snart ved at være træt af mig selv, og min manglende
korrekturlæsning.

I eksemplet nedenfor bliver der ikke shiftet til venstre, men
til højre.

> Fordi resultatet ikke bliver, som man skulle vente.
> Et hurtigt lille 8-bit signed-eksempel:
> Tallet -104 (1001 1000) skal shiftes en bit til højre.
> Resultat: 1100 1100
> Hvis det havde været unsigned, så havde resultatet været et
> helt andet (og det man skulle forvente), nemlig 0100 1100.

Men ideen er god nok. Rækkefølgen laves om ved signed variabler.

Det er vist ved at være sengetid...

--
Vh Morten



Tomas Christiansen (13-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 13-04-01 23:11

Morten Fast skrev:
> Hvis jeg prøver med &H7FFFFFFF så får jeg &H7FFFFFFE,
> ganske som jeg burde ved signed datatyper:
>
> &H7FFFFFFF = 0111 1111 1111 1111 1111 1111 1111 1111
> &H7FFFFFFE = 0111 1111 1111 1111 1111 1111 1111 1110
>
> Hvis jeg prøver med &H80000001 så får jeg &H80000002:
>
> &H80000001 = 1000 0000 0000 0000 0000 0000 0000 0001
> &H80000002 = 1000 0000 0000 0000 0000 0000 0000 0010
>
> Husk at den øverste bit afgør om tallet er positivt eller
> negativt. Den bliver ikke flyttet med.
> Tallet er reelt kun 31 bit stort.
>
> Funktionen både virker og regner rigtigt.

Okay! Nu gik der en prås op for mig.

Du opfatter altså Flemming Klug's oprindelige spørgsmål "Jeg leder forgæves
efter kommandoer som SHR og SHL i Visual Basic" som at han mangler
aritmetisk venstre/højre skift, og jeg opfatter det som at han mangler
logisk venstre/højreskift.

Det hele afhænger af hvordan man definerer SHR og SHL, og det afhænger vel
af hvilket sprog man "kommer fra" (hvordan denne eller en lignende funktions
virkemåde er defineret).

Jeg valgte at tage udgangspunkt i assemblerverdenen, hvor SHL/SHR typisk er
defineret som logisk venstre/højre-skift, og hvor man f.eks. benytter
betegnelserne SAL/SAR for aritmetisk venstre/højre-skift.

Konklusion: Vi har begge ret, vores forudsætninger var blot forskellige...
-------
Tomas



Tomas Christiansen (13-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 13-04-01 23:34

Morten Fast skrev:
> Hvis jeg prøver med &H7FFFFFFF så får jeg &H7FFFFFFE,
> ganske som jeg burde ved signed datatyper:
>
> &H7FFFFFFF = 0111 1111 1111 1111 1111 1111 1111 1111
> &H7FFFFFFE = 0111 1111 1111 1111 1111 1111 1111 1110
>
> Hvis jeg prøver med &H80000001 så får jeg &H80000002:
>
> &H80000001 = 1000 0000 0000 0000 0000 0000 0000 0001
> &H80000002 = 1000 0000 0000 0000 0000 0000 0000 0010
>
> Husk at den øverste bit afgør om tallet er positivt eller
> negativt. Den bliver ikke flyttet med.
> Tallet er reelt kun 31 bit stort.
>
> Funktionen både virker og regner rigtigt.

Okay! Nu gik der en prås op for mig.

Du opfatter altså Flemming Klug's oprindelige spørgsmål "Jeg leder forgæves
efter kommandoer som SHR og SHL i Visual Basic" som at han mangler
en form for aritmetisk venstre/højre skift, og jeg opfatter det som at han
mangler
logisk venstre/højreskift.

Det hele afhænger af hvordan man definerer SHR og SHL, og det afhænger vel
af hvilket sprog man "kommer fra" (hvordan denne eller en lignende funktions
virkemåde er defineret).

Jeg valgte at tage udgangspunkt i assemblerverdenen, hvor SHL/SHR typisk er
defineret som logisk venstre/højre-skift, som ikke opfatter eventuelle
fortegnsbit som noget der skal specielt (andet end at der ved udførelse af
operationen sættes et flag, hvis fortegnsskift har fundet sted).

Konklusion: Vi har begge ret, vores forudsætninger var blot forskellige...
-------
Tomas



Morten Fast (14-04-2001)
Kommentar
Fra : Morten Fast


Dato : 14-04-01 09:25


"Tomas Christiansen" <toc@blikroer.removethis.dk> wrote in message
news:I9LB6.645$JR4.8344@news.get2net.dk...

> Det hele afhænger af hvordan man definerer SHR og SHL, og det
> afhænger vel af hvilket sprog man "kommer fra" (hvordan denne
> eller en lignende funktions virkemåde er defineret).

SHR/SHL er _ALTID_ et spørgsmål om at dividere/multiplicere med 2.

Altid. Og i alle sprog.

Det ligger i talopbygningens natur:

.... 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
----------------------------------------
.... 128 64 32 16 8 4 2 1

Hver gang der rykkes en bit til venstre, er tallet blevet
ganget med 2. Og omvendt.

Når tallet er af en sådan størrelse, at - ved shift
left - den øverste bit forsvinder, så bliver talværdien
ikke det, der svarer til en multiplicering med 2, men det
er udelukkende fordi datatypen ikke kan indeholde et så
stort resultat. Funktionsmæssigt er det det samme.

Det, der er hele humlen omkring SHR/SHL i VB, er at VB kun
bruger signed datatyper (med undtagelse af typen Byte, der
er unsigned).

Signed variabler har en bit mindre at gøre godt med.
Der angiver den øverste bit nemlig tallets fortegn,
og tallets øverste bit, er derfor datatypens næstøverste.

Det bliver noget rigtigt grimt noget, når man kigger på
bitrækkefølgen ved negative tal, og derfor bør man heller
ikke shifte signed variabler (hvilket vel egentlig også
er grunden til at VB ikke har en medfødt SHR/SHL-funktion).

Men SHR/SHL er stadig et spørgsmål om at
dividere/multiplicere med 2.

--
Vh Morten



Tomas Christiansen (14-04-2001)
Kommentar
Fra : Tomas Christiansen


Dato : 14-04-01 23:27

Morten Fast skrev:
> SHR/SHL er _ALTID_ et spørgsmål om at dividere/multiplicere med 2.
....
> Altid. Og i alle sprog.
....
> Signed variabler har en bit mindre at gøre godt med.
> Der angiver den øverste bit nemlig tallets fortegn,
> og tallets øverste bit, er derfor datatypens næstøverste.

Okay. Kan du så forklare mig, hvorfor der i dokumentation til 80*86
assembler er beskrevet følgende:

SHL : The shl/sal instruction multiplies both signed and unsigned values by
two for each shift...this instruction sets the overflow flag if the signed
result does not fit in the destination operation. This occurs when you shift
a zero into the H.O. bit of a negative number or you shift a one into the
H.O. bit of a non-negative number.

--> Med andre ord opfattes HO bit som en del af tallet.

SHR : Remember that division by two using shr only works for unsigned
operands. If ax contains -1 and you execute shr ax, 1 the result in ax will
be 32767 (7FFFh), not -1 or zero as you would expect. Use the sar
instruction if you need to divide a signed integer by some power of two.

--> Med andre ord bliver resultatet af et højreskift på et signed 16-bit tal
med værdien FFFFh altså 7FFFh. Hvis man ønsker at tage specielt hånd om
fortegnsbitten, skal man bruge instruktionen SAR.

Check selv - f.eks. her:
http://webster.cs.ucr.edu/Page_asm/ArtofAssembly/CH06/CH06-3.html#HEADING3-4
2

Der står også lidt generelt om f.eks. højreskift:

"To use the shift right as a division operator, we must define a third shift
operation: arithmetic shift right. An arithmetic shift right works just like
the normal shift right operation (a logical shift right) with one exception:
instead of shifting a zero into bit seven, an arithmetic shift right
operation leaves bit seven alone, that is, during the shift operation it
does not modify the value of bit seven as shown below"

-------
Tomas



Morten Fast (15-04-2001)
Kommentar
Fra : Morten Fast


Dato : 15-04-01 07:49


"Tomas Christiansen" <toc@blikroer.removethis.dk> wrote in message
news:F84C6.384$BM5.7909@news.get2net.dk...

> Morten Fast skrev:
> > SHR/SHL er _ALTID_ et spørgsmål om at dividere/multiplicere
> > med 2.

> SHL : The shl/sal instruction multiplies both signed and
> unsigned values by two for each shift

Hmmm... Hvor er vi uenige?

> ...this instruction sets the overflow flag if the signed
> result does not fit in the destination operation. This occurs
> when you shift a zero into the H.O. bit of a negative number
> or you shift a one into the H.O. bit of a non-negative number.
> --> Med andre ord opfattes HO bit som en del af tallet.

Nej, du får godt nok lov til at beholde din bitrækkefølge, men
du får en overflow-fejl. Den øverste bit er ikke en del af
talværdien ved signed variabler.

> SHR : Remember that division by two using shr only works for
> unsigned operands.
> --> Med andre ord bliver resultatet af et højreskift på et
> signed 16-bit tal med værdien FFFFh altså 7FFFh.

Fordi SHR kun virker fornuftigt på unsigned datatyper,
ganske som dokumentationen foreskriver.

For at gøre en lang historie kort (det er vist lidt for
sent nu... , så bruger assembler SHR/SHL til unsigned
datatyper, og SAR/SAL til signed datatyper, og alle fire
funktioner virker ved division/mulitplikation.

Logisk skift bruges kun på unsigned datatyper, og tager
ikke højde for den øverste bit.
På unsigned datatyper svarer SHL/SHR til at
multiplicere/dividere.

Artitmetisk skift bruges kun på signed datatyper, og tager
højde for fortegnet.
På signed datatyper svarer SAL/SAR til at
multiplicere/dividere.

I assembler har man lavet fire funktioner for at kunne tage
højde for datatypen, i f.eks. C++ er shiftoperatørerne
overstyret, så man bruger den samme på alle datatyper, og
så finder funktionen selv ud af hvordan den skal behandle
datatypen.

Logisk eller aritmetisk? Det er et spørgsmål om datatypen,
men det ændrer ikke det faktum, at det stadigvæk kun er et
spørgsmål om at multiplicere eller dividere.

--
Vh Morten



Per Madsen (11-04-2001)
Kommentar
Fra : Per Madsen


Dato : 11-04-01 17:46

Mener du ikke:

Function ShiftLeft(Tal As Long) As Long

ShiftLeft = (Tal And &H7FFFFFFF) * 2

End Function

mhv

Per


"Morten Fast" <usenet@freestate.dk> wrote in message
news:9b1vr4$ici$1@news.inet.tele.dk...
>
> "Thomas J." <pppp@europe.com> wrote in message
> news:9avq7g$n4n$1@news.inet.tele.dk...
> > Kunne det ikke resultere i en "overflow"?
> > Nogen løsning ?
>
> Problemet med overflow vil kun opstå i forbindelse med Shift Left.
>
> Tomas har givet et par eksempler på hvordan Shift Left kan løses,
> men det kan gøres endnu kortere. Du fjerner blot den øverste bit:
>
> Function ShiftLeft(Tal As Long) As Long
>
> ShiftLeft = (Tal And &H80000000) * 2
>
> End Function
>
> --
> Vh Morten
>
>



Morten Fast (11-04-2001)
Kommentar
Fra : Morten Fast


Dato : 11-04-01 20:34


"Per Madsen" <per_madsen@pmlotto.dk> wrote in message
news:VT%A6.3228$mj.200976@news101.telia.com...

> Mener du ikke:

Jo, selvfølgelig.
Det gik lidt for stærkt. Damn!

--
Vh Morten



Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408527
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste