Wednesday 27 December 2017

Aritmetisk shift höger binära alternativ


När man skifter åt vänster är det ingen skillnad mellan aritmetisk och logisk växling. När du växlar rätt, beror typen av växling på typen av värdet som förskjuts. (Som bakgrund för de läsare som inte känner till skillnaden, skiftar en logisk högerförskjutning med 1 bit alla bitarna till höger och fyller i den längsta delen med en 0. Ett aritmetiskt skifte lämnar det ursprungliga värdet i den vänstra biten. Skillnaden blir viktig när man hanterar negativa tal.) När man byter ett osignerat värde är operatören i C en logisk växling. När man skifter ett signerat värde är operatören ett aritmetiskt skifte. Till exempel antar en 32 bitars maskin: svarat 11 aug 08 kl 9:16 Så nära, Greg. Din förklaring är nästan perfekt, men att ändra ett uttryck för signerat typ och negativt värde är implementeringsdefinierat. Se ISOIEC 9899: 1999 Avsnitt 6.5.7. ndash Rob Sep 22 08 at 22:53 Rob: För vänsterskift och signerat negativt tal är beteendet odefinierat. ndash JeremyP Apr 4 12 at 15:24 Faktiskt resulterar vänsterskift också i odefinierat beteende för positiva signerade värden om det resulterande matematiska värdet (vilket inte är begränsat i bitstorlek) kan representeras som ett positivt värde i den signerade typen. Grunden är att du måste tråka försiktigt när du skifter ett signerat värde rätt. ndash Michael Burr 21 juni kl 13:30 Först är skillnaden mellan logiska och aritmetiska skift från en matematisk synvinkel utan att oroa sig för datatypstorlek. Logiska skift fyller alltid bortkastade bitar med nollor medan aritmetisk skift fyller det med nollor endast för vänsterskift, men för rätt skift kopierar den MSB och därigenom bevarar signalen för operand (förutsatt att två komplementkodning för negativa värden). Med andra ord ser det logiska skiftet på den förskjutna operanden som bara en ström av bitar och rör dem utan att stör om tecknet på det resulterande värdet. Aritmetisk skift ser på det som ett (signerat) nummer och bevarar tecknet eftersom skift görs. En vänster aritmetisk växling av ett tal X med n är ekvivalent med att multiplicera X med 2 n och motsvarar sålunda logisk vänsterskift. Ett logiskt skift skulle också ge samma resultat eftersom MSB faller ändå av slutet och det finns inget att behålla. En rätt aritmetisk förskjutning av ett tal X med n motsvarar heltalsdelningen av X med 2 n ENDAST om X är icke-negativ Integersektion är ingenting annat än matematisk delning och runda mot 0 (trunc). För negativa siffror representerade av två komplementkodning, som skiftar direkt med n-bitar, har effekten att matematiskt dela upp den med 2 n och avrundning mot (våning) så att rätt skiftning skiljer sig åt för icke-negativa och negativa värden. för X 0, X n X 2 n trunc (X 2 n) för X lt 0, X n våning (X 2 n) var är matematisk delning, är heltal division. Låt oss titta på ett exempel: 37 2 18 (avrundning 18.5 mot 0) 10010) 2 resultat av aritmetisk högerförskjutning -37) 10 11011011) 2 (med tanke på ett två komplement, 8-bitars representation) -37 2 -18 (avrundning 18,5 mot 0) 11101110) 2 INTE resultatet av aritmetisk högerförskjutning -37 1 -19 (avrundning 18.5 mot) 11101101) 2 resultat av aritmetisk rättväxling Som Guy Steele påpekade. Denna skillnad har lett till fel i mer än en kompilator. Här kan icke-negativ (matematik) kartläggas till osignerade och signerade icke-negativa värden (C) båda behandlas lika och högerväxlande dem görs med heltal. Så logisk och aritmetisk är likvärdig i vänsterförskjutning och för icke-negativa värden i rätt förskjutning i rätt växling av negativa värden som de skiljer sig åt. Operand och resultattyper Standard C99 6.5.7: Varje operand ska ha heltalstyper. Heltalskampanjerna utförs på var och en av operandema. Resultatets typ är den för den främsta vänstra operand. Om värdet på den högra operand är negativt eller är större än eller lika med bredden på den främjade vänstra operand, är beteendet odefinierat. I ovanstående snipp blir båda operanderna int (på grund av heltalstillägg) om E2 var negativ eller E2 sizeof (int) CHARBIT då operationen är odefinierad. Detta beror på att skiftande mer än de tillgängliga bitarna säkert går över. Hade R deklarerats som kort. Int resultatet av skiftoperationen skulle implicit konverteras till korta en förminskningsomvandling, vilket kan leda till implementeringsdefinierat beteende om värdet inte är representativt i destinationstypen. Vänsterförskjutning Resultatet av E1 ltlt E2 är E1 vänsterförskjutna E2-bitpositioner lediga bitar fylls med nollor. Om E1 har en osignerad typ, är resultatet av E12 E2. reducerad modulo en mer än det maximala värdet representerar i resultattypen. Om E1 har ett signerat typ och ett icke-negativt värde, och E12 E2 är representativt i resultattypen, då är det resulterande värdet annars är beteendet odefinierat. Eftersom vänsterskift är lika för båda, är de lediga bitarna helt enkelt fyllda med nollor. Det står då att för både osignerade och signerade typer är det ett aritmetiskt skifte. Jag tolkar det som aritmetiskt skift eftersom logiska skift inte stör om det värde som representeras av bitarna, det ser bara på det som en ström av bitar men standarden talar inte i bitar, men genom att definiera det i förhållande till det värde som erhålls av produkten av E1 med 2 E2. Tillvägagångssättet här är att för tecknade typer bör värdet vara negativt och det resulterande värdet ska vara representativt i resultattypen. Annars är operationen odefinierad. Resultattypen skulle vara typen av E1 efter att ha tillämpat integrerad marknadsföring och inte destinationen (variabeln som kommer att hålla resultatet). Det resulterande värdet omvandlas implicit till destinationstypen om det inte är representativt för den typen, då omvandlingen är implementeringsdefinierad (C99 6.3.1.33). Om E1 är en signerad typ med negativt värde är beteendet för vänsterskiftning odefinierat. Detta är en enkel väg till odefinierat beteende som lätt kan förbises. Höger Skift Resultatet av E1 E2 är E1-riktiga E2-bitpositioner. Om E1 har en osignerad typ eller om E1 har en signerad typ och ett icke-negativt värde, är värdet av resultatet den integrerade delen av kvoten E12 E2. Om E1 har en signerad typ och ett negativt värde är det resulterande värdet implementeringsdefinierat. Rätt skift för osignerade och signerade icke-negativa värden är ganska rakt framåt, de lediga bitarna är fyllda med nollor. För signerade negativa värden är resultatet av rätt skiftning implementeringsdefinierat. Med det sagt, implementerar de flesta implementationer som GCC och Visual C högerväxling som aritmetisk skiftning genom att bevara teckenbiten. Slutsats Till skillnad från Java, som har en speciell operator gtgtgt för logisk förskjutning från den vanliga gtgt och ltlt. C och C har bara aritmetisk skiftning med vissa områden odefinierade och implementeringsdefinierade. Anledningen till att jag anser dem som aritmetiska beror på standardformuleringen operationen matematiskt istället för att behandla den förskjutna operanden som en ström av bitar, detta är kanske orsaken till att det lämnar dessa områden oanpassade i stället för att bara definiera alla fall som logiska skift. När det gäller vilken typ av växling du får är den viktiga saken av det värde som du flyttar. En klassisk källa till buggar är när du byter en bokstavlig, till exempel maskerad bitar. Om du till exempel vill släppa den vänstra delen av ett unsigned heltal, kan du prova detta som din mask: Tyvärr kommer det att leda dig till problem eftersom masken kommer att ha alla sina bitar inställda eftersom värdet flyttas (0) signeras, sålunda utförs en aritmetisk skift. Istället vill du tvinga ett logiskt skifte genom att uttryckligen förklara värdet som osignerat, dvs genom att göra något så här: Jo, jag tittade på wikipedia. och de har detta att säga: C har dock bara en högerförskjutningsoperatör,. Många C-kompilatorer väljer vilken rättskift som ska utföras beroende på vilken typ av heltal som ska skiftas, ofta undertecknade heltal skiftas med hjälp av det aritmetiska skiftet, och osignerade heltal flyttas med hjälp av det logiska skiftet. Så det låter som det beror på din kompilator. Också i den artikeln noterar att vänsterskiftet är detsamma för aritmetiska och logiska. Jag skulle rekommendera att göra ett enkelt test med några signerade och osignerade nummer på gränsfallet (hög bit uppsättning förstås) och se vad resultatet är på din kompilator. Jag skulle också rekommendera att undvika beroende på att det är ett eller annat eftersom det verkar att C inte har någon standard, åtminstone om det är rimligt och möjligt att undvika sådant beroende. svarat den 11 augusti 08 kl 9:18 Även om de flesta C-kompilatorer brukade ha en aritmetisk vänsterförskjutning för signerade värden, verkar ett sådant användbart beteende ha blivit avlägsnat. Nuvarande kompilatorsfilosofi verkar vara att anta att resultatet av en vänsterskift på en variabel berättigar en kompilator för att anta att variabeln måste vara icke-negativ och sålunda utelämna någon kod någon annanstans som skulle vara nödvändig för korrekt beteende om variabeln var negativ . ndash supercat Apr 16 15 at 5:47 Vänster shift ltlt Det här är något lätt och när du använder shift operatören är det alltid en bitvis operation, så vi kan inte använda den med en dubbel och flytande operation. När vi lämnade skift en noll, läggs den alltid till den minst signifikanta biten (LSB). Men i rätt skift måste vi följa en ytterligare regel och den här regeln kallas teckenbitskopia. Betydelsen av teckenbit kopia är om den mest signifikanta biten (MSB) är inställd, sedan efter en höger skift igen, kommer MSB att ställas om den återställdes då den återställs, betyder att om det föregående värdet var noll då efter att ha skiftats igen bit är noll om föregående bit var en då efter skiftet är det igen en. Denna regel gäller inte för vänsterskift. Det viktigaste exemplet på högerskift om du ändrar ett negativt tal till högerskiftet, då efter något skift, når värdet äntligen till noll och därefter efter detta om skiftet -1 blir valfritt antal gånger detsamma. Vänligen kolla. svarade mar 30 14 kl 11:04 Rätt nu läser jag boken Computer Systems. Programmer Perspektiv. Ett problem i boken säger att utföra en logisk rätt skift på ett signerat heltal, jag kan inte räkna ut hur man börjar med detta. Följande är den faktiska frågan från boken. Fyll i kod för följande C-funktioner. Funktionen srl utför ett logiskt högerskift med hjälp av ett aritmetiskt högerförskjutning (ges av värdet xsra), följt av andra operationer som inte inkluderar rätt skift eller delning. Funktionssra utför ett aritmetiskt rättskifte med hjälp av ett logiskt högerförskjutning (givet av värdet xsrl), följt av andra operationer som inte inkluderar rätt skift eller delning. Du kan använda beräkningen 8sizeof (int) för att bestämma w, antalet bitar i datatyp int. Skiftmängden k kan variera från 0 till w 1. Jag hoppas du förstår nu frågan. frågade 27 juli kl 13:18 Jag kommer inte ge dig ett komplett svar eftersom det här tydligen är läxor, men jag ger dig några tips som hjälper dig att göra det själv: för en logisk rätt skiftning av N bitar måste du rensa toppen N bitar av resultatet efter aritmetisk skiftning kan du rensa bitar i ett värde genom att applicera en lämplig mask. typiskt med hjälp av bitwise AND eller XOR för att rensa de övre N bitarna av ett värde som du behöver en mask med N 0s och resterande bitar 1 kan du skapa en lämplig mask med vänsterskift med W-N bitar, där W är antalet bitar i ett ord (som du kan beräkna som W sizeof (int) CHARBIT) T. ex. för en logisk högerförskjutning med 3 Den svåraste delen genererar masken, men om du tänker på vänsterskift appliceras så ett lämpligt värde, kanske följt av en ytterligare bitvis operation, ska du snart se en ganska enkel lösning. Är det resulterande mönstret korrekt representation för -164 Nej. Resultatet representerar ett stort positivt tal, inte -4 Skift Höger Aritmetik En rätt skiftlogik kan inte användas för att dela ett negativt heltal med två. Problemet är att ett skift rätt logiskt flyttar nollor till högorderbiten. Detta är önskvärt i vissa situationer, men inte för att dividera negativa heltal där den höga ordningsbiten är teckenbiten. En aritmetisk högerskift replikerar teckenbiten som behövs för att fylla bitpositioner: FRÅGA 13: Finns det ett behov av en aritmetisk skiftlängd instruktion

No comments:

Post a Comment