უფრო რთული ლოგიკური ელემენტები. ძირითადი ლოგიკური ოპერაციები. AND, NOT, OR და XOR (ექსკლუზიური ან) ექსკლუზიური ან

ქცევა

Exclusive OR, Exclusive NOR, კენტი და ლუწი ელემენტები ითვლის შეყვანის მნიშვნელობების შესაბამის ფუნქციას და გამოსცემს შედეგს.

ნაგულისხმევად, დაუკავშირებელი შეყვანები იგნორირებულია - ანუ, თუ შეყვანები რეალურად არ არის დაკავშირებული მათთან - არც მავთულები. ასე რომ, თქვენ შეგიძლიათ დაამატოთ 5 შეყვანის ელემენტი, მაგრამ დააკავშიროთ მხოლოდ ორი შეყვანა და ის იმოქმედებს როგორც 2 შეყვანის ელემენტი; ეს გიხსნით ყოველი ელემენტის შექმნისას შეყვანის რაოდენობის დაყენებაზე ფიქრისგან. (თუ ყველა შეყვანა არ არის დაკავშირებული, მაშინ შეცდომის მნიშვნელობა გამოსავალზე არის X.) თუმცა, ზოგიერთი მომხმარებელი ურჩევნია Logisim-მა დაჟინებით მოითხოვოს ყველა შეყვანის დაკავშირება, რადგან ეს შეესაბამება რეალურ ელემენტებს. თქვენ შეგიძლიათ ჩართოთ ეს ქცევა პროექტი > ოფციები..., მოდელირების ჩანართზე გადასვლით და გაურკვევლობაში ელემენტის გამომავალი შეუსაბამობისთვის შეცდომის არჩევით.

ელემენტების ორი შეყვანის სიმართლის ცხრილი შემდეგია.

xექსკლუზიური OR ექსკლუზიური თუ არაუცნაური პარიტეტიპარიტეტი
0 0 0 1 0 1
0 1 1 0 1 0
1 0 1 0 1 0
1 1 0 1 0 1

როგორც ხედავთ, Odd და XOR კარიბჭეები ერთნაირად იქცევიან ორი შეყვანის შემთხვევაში; ანალოგიურად, პარიტეტული და ექსკლუზიური NOR ელემენტები ერთნაირად იქცევიან. მაგრამ თუ ორზე მეტი შეყვანაა გარკვეული მნიშვნელობით, მაშინ Exclusive OR ელემენტი გამოსცემს 1-ს, როდესაც ერთი არის ზუსტად ერთი შეყვანა, ხოლო კენტი ელემენტი გამოსცემს 1-ს, როდესაც არის ერთი შეყვანის კენტ რაოდენობაზე. XOR კარიბჭე გამოიმუშავებს 1-ს გამოსავალზე, როდესაც ერთთან შეყვანები მკაცრად არის არაერთი, ხოლო პარიტეტის ელემენტი მისცემს 1-ს, როდესაც არის ლუწი რაოდენობის შენატანი ერთით. XOR და XNOR კარიბჭეებს აქვთ ატრიბუტი სახელწოდებით Multi-Input Behavior, რომელიც საშუალებას აძლევს მათ კონფიგურაციას გამოიყენონ კენტი და ლუწი კარიბჭის ქცევა.

თუ რომელიმე შენატანს აქვს შეცდომის მნიშვნელობა (მაგალითად, თუ კონფლიქტური მნიშვნელობები მიეწოდება იმავე მავთულს) ან მცურავი მნიშვნელობა, მაშინ გამომავალი იქნება შეცდომის მნიშვნელობა.

თითოეული ელემენტის მრავალბიტიანი ვერსიები შეასრულებენ თავიანთ ერთბიტიან კონვერტაციებს შეყვანებზე ბიტალურად.

შენიშვნა:ბევრი ექსპერტი ამტკიცებს, რომ XOR ხვეული ელემენტის ქცევა უნდა შეესაბამებოდეს კენტი ელემენტის ქცევას, მაგრამ ამ საკითხზე შეთანხმება არ არსებობს. Logisim-ის ნაგულისხმევი ქცევა XOR ელემენტისთვის ეფუძნება IEEE 91 სტანდარტს, ეს ასევე შეესაბამება ტერმინის ინტუიციურ გაგებას ექსკლუზიური OR: მიმტანი, რომელიც გეკითხებათ, გსურთ თუ არა კარტოფილის პიურეს, სტაფილოს, მწვანე ბარდას ან შლაპის გვერდითი კერძი, მიიღებს მხოლოდ ერთ არჩევანს და არა სამს, რაც არ უნდა გითხრათ ექსპერტებმა. (თუმცა, უნდა ვაღიარო, რომ სერიოზულად არ გამომიცდია ეს განცხადება.) თქვენ შეგიძლიათ დააკონფიგურიროთ XOR და XNOR კარიბჭეები, რათა გამოიყენონ ერთ-ერთი ვარიანტი მისი მრავალ შეყვანის ქცევის ატრიბუტის შეცვლით.

კონტაქტები (იმ პირობით, რომ კომპონენტი აღმოსავლეთისკენ არის მიმართული)

დასავლეთის კიდე (შეყვანები, ბიტის სიგანე შეესაბამება მონაცემთა ბიტების ატრიბუტს)

კომპონენტების შეყვანა. იქნება იმდენი მათგანი, რამდენიც მითითებულია შეყვანის რაოდენობა ატრიბუტში.

გაითვალისწინეთ, რომ თუ იყენებთ ხვეულ ელემენტებს, XOR და XNOR ელემენტების დასავლეთი კიდე მოხრილი იქნება. თუმცა, შეყვანის ქინძისთავები თითქმის არ არის განთავსებული. ამის საჩვენებლად Logisim ხატავს მოკლე სეგმენტებს; თუ თქვენ გადაფარავთ სეგმენტს, პროგრამა გაფრთხილების გარეშე ივარაუდება, რომ თქვენ არ აპირებთ მის გადაფარვას. "Print View"-ს გამოყენებისას ეს სეგმენტები არ იქნება დახატული, თუ ისინი არ არის დაკავშირებული სადენებთან.

აღმოსავლეთის კიდე (გამომავალი, ბიტის სიგანე შეესაბამება მონაცემთა ბიტების ატრიბუტს)

ელემენტის გამომავალი, რომლის ღირებულება გამოითვლება შეყვანებზე მიმდინარე მნიშვნელობების საფუძველზე, როგორც ზემოთ აღწერილი.

ატრიბუტები

როდესაც კომპონენტი არჩეულია ან უკვე დამატებულია, 0-დან 9-მდე კლავიშები ცვლის შეყვანის რაოდენობას, Alt-0-დან Alt-9 ცვლის მონაცემთა ბიტების ატრიბუტს და ისრიანი კლავიშები ცვლის მიმართულების ატრიბუტს.

მიმართულება კომპონენტის მიმართულება (მისი გამომავალი შეყვანის მიმართ).


მონაცემთა ბიტები კომპონენტის შეყვანისა და გამომავალი სიგანე. ელემენტის ზომა განსაზღვრავს კომპონენტის ფართო თუ ვიწრო ვერსიას. ეს არ იმოქმედებს შეყვანის რაოდენობაზე, რომელიც განისაზღვრება შეყვანის რაოდენობა ატრიბუტით; თუმცა, თუ შეყვანის რაოდენობა აღემატება 3-ს (ვიწრო კომპონენტისთვის) ან 5-ს (ფართოსთვის), მაშინ ელემენტი გადაიცემა "ფრთებით" შეყვანის მოთხოვნილი რაოდენობის დასაკმაყოფილებლად. შეყვანების რაოდენობა ადგენს, რამდენი ქინძისთავები ექნება კომპონენტს დასავლეთ კიდეზე.
მრავალ შეყვანის ქცევა (მხოლოდ XOR და XNOR) როდესაც არის სამი ან მეტი შეყვანა, XOR და XNOR კარიბჭეების გამომავალი იქნება დაფუძნებული იმ ფაქტზე, რომ 1 არის მკაცრად ერთი შეყვანა (ნაგულისხმევი) ან შეყვანის კენტი რაოდენობა. . ოპერატორი სინტაქსი აღწერა
და A და B შეერთება: თუ A და B არის True, მაშინ True. წინააღმდეგ შემთხვევაში - ყალბი
ან A OR B განშორება: თუ რომელიმე ოპერანდი არის True, მაშინ True. წინააღმდეგ შემთხვევაში - ყალბი
არა არა ა უარყოფა: თუ A არის მცდარი, მაშინ ის მართალია. წინააღმდეგ შემთხვევაში - ყალბი
XOR A XOR B გამონაკლისი: თუ A არის True ან B არის True, მაშინ - True. წინააღმდეგ შემთხვევაში - ყალბი
EQV A EQV B ეკვივალენტობა: თუ A-ს აქვს იგივე მნიშვნელობა, რაც B, მაშინ ეს არის True. წინააღმდეგ შემთხვევაში - ყალბი

IMP

IMP B

მინიშნება:

თუ A არის True და B არის მცდარი, მაშინ მცდარი. წინააღმდეგ შემთხვევაში - მართალია
ლოგიკური ოპერატორის ოპერანდი შეიძლება იყოს ნებისმიერი მოქმედი გამოხატულება, რომელსაც აქვს ლოგიკური შედეგი, ასევე რიცხვი, რომელიც შეიძლება გარდაიქმნას ლოგიკურ მნიშვნელობად.


ლოგიკური ოპერაციის შედეგი არის ლოგიკური ტიპის მნიშვნელობა (ან Null, თუ ოპერანდებიდან ერთი მაინც არის Null). ლოგიკური ოპერატორი AND.

სინტაქსი:


Operand_1 და Operand_2


AND ოპერატორი ასრულებს


ლოგიკური შეერთება


ამ ოპერაციის შედეგი არის True მხოლოდ მაშინ, როდესაც ორივე ოპერანდი არის True, წინააღმდეგ შემთხვევაში False.

სიმართლის ცხრილი

თუ A არის True და B არის მცდარი, მაშინ მცდარი. წინააღმდეგ შემთხვევაში - მართალია
Operand_1 ან Operand_2


OR ოპერატორი აკეთებს ლოგიკური განცალკევება.

ამ ოპერაციის შედეგი არის True, თუ ოპერანდებიდან ერთი მაინც არის True, წინააღმდეგ შემთხვევაში False.


Operand_1 და Operand_2


OR ოპერატორი შეიძლება გამოყენებულ იქნას მრავალი ოპერანდისთვის:


(5 3) ან (5=6) შედეგი იქნება True


ოპერანდების რაოდენობის მიუხედავად, ლოგიკური OR მოქმედების შედეგი ყოველთვის იქნება True, თუ გამოხატვის ოპერანდებიდან ერთი მაინც არის True. წინააღმდეგ შემთხვევაში შედეგი იქნება ყალბი.

AND და OR ოპერატორები შეიძლება გაერთიანდეს:


((5 3)) ან (5=6) შედეგი იქნება True

ლოგიკური ოპერატორი NOT

თუ A არის True და B არის მცდარი, მაშინ მცდარი. წინააღმდეგ შემთხვევაში - მართალია
არა ოპერანდი


NOT ოპერატორი აკეთებს ლოგიკური უარყოფა.

NOT ოპერატორი იყენებს მხოლოდ ერთ ოპერანდს.


Operand_1 და Operand_2


და ან არა ოპერატორები შეიძლება გაერთიანდეს:


((5 3)) ან არა (5=6) შედეგი იქნება True

ლოგიკური ოპერატორი XOR

თუ A არის True და B არის მცდარი, მაშინ მცდარი. წინააღმდეგ შემთხვევაში - მართალია
Operand_1 XOR Operand_2


XOR ოპერატორი აკეთებს ლოგიკური გამონაკლისი.

ამ ოპერაციის შედეგი არის True, თუ ოპერანდებს აქვთ განსხვავებული მნიშვნელობები, წინააღმდეგ შემთხვევაში False.


Operand_1 და Operand_2


((5 3)) ან არა (5=6) XOR (5=5) შედეგი იქნება მცდარი

ლოგიკური ოპერატორი EQV

თუ A არის True და B არის მცდარი, მაშინ მცდარი. წინააღმდეგ შემთხვევაში - მართალია
Operand_1 EQV Operand_2


EQV ოპერატორი არის ოპერატორი ლოგიკური ეკვივალენტობა.

ამ ოპერაციის შედეგი არის True, თუ ოპერანდებს აქვთ იგივე მნიშვნელობები, წინააღმდეგ შემთხვევაში False.


Operand_1 და Operand_2


((5 3)) ან არა (5=6) EQV (5=5) შედეგი იქნება True

ლოგიკური ოპერატორი IMP

თუ A არის True და B არის მცდარი, მაშინ მცდარი. წინააღმდეგ შემთხვევაში - მართალია
Operand_1 IMP Operand_2


IMP ოპერატორი ასრულებს ლოგიკურ ოპერაციას შედეგები.


Operand_1 და Operand_2


((5 3)) ან არა (5=6) IMP (5=5) შედეგი იქნება True


IMP ლოგიკური ოპერატორი ყველაზე ნაკლებად ინტუიციურია ყველა ლოგიკურ ოპერატორს შორის. საბედნიეროდ, მისი გამოყენების აუცილებლობა საკმაოდ იშვიათად ხდება.

ტეგები: C-ბიტიანი ოპერაციები, ბიტიანი ოპერაციები, ბიტების შეკრება, ბიტების გამრავლება, ბიტების ცვლა მარცხნივ, ბიტების გადანაცვლება მარჯვნივ

შესავალი

C ენას ზოგჯერ მაკროასამბლერს უწოდებენ, ტექნიკისადმი მისი მიახლოების გამო. თუ არ იყენებთ ოპტიმიზაციას, შეგიძლიათ უხეშადაც კი შეაფასოთ, რომელ ასამბლეის ენაში გადაიყვანება პროგრამის კოდი. ენის სიმარტივე და მინიმალიზმი (ენის სიმარტივე არ უნდა ავურიოთ ენაში პროგრამირების სიმარტივეში) განაპირობა ის, რომ ბევრ პლატფორმაზე C რჩება ერთადერთ მაღალი დონის პროგრამირების ენად. ბიტიური ოპერაციების მიმოხილვის გარეშე, რა თქმა უნდა, ენის სწავლა არასრული იქნებოდა.

Bitwise ოპერაციები, როგორც სახელი გულისხმობს, საშუალებას გაძლევთ იმუშაოთ პირდაპირ ბიტებზე. Bitwise ოპერაციების გამოყენების უამრავი მაგალითი შეგიძლიათ იხილოთ, მაგალითად, ჰენრი უორენის წიგნში "ალგორითმული ხრიკები პროგრამისტებისთვის". აქ განვიხილავთ მხოლოდ თავად ოპერაციებს და პრიმიტიულ ალგორითმებს.

ბიტალურად AND, OR, NOT, XOR

ჯერ შეგახსენებთ, რომ ლოგიკური ოპერაციები AND, OR, ექსკლუზიური OR და NOT შეიძლება აღწერილი იყოს სიმართლის ცხრილების გამოყენებით.

ლოგიკური ოპერატორი NOT
X არა X
0 1
1 0

ბიტიან ოპერაციებში, 1-ის ბიტის მნიშვნელობა განიხილება, როგორც ლოგიკური true და 0, როგორც false. Bitwise AND (& ოპერატორი) იღებს ორ რიცხვს და ლოგიკურად ამრავლებს შესაბამის ბიტებს. მაგალითად, თუ ლოგიკურად გაამრავლებთ 3-ს 8-ზე, მიიღებთ 0-ს

Char a = 3; char b = 8; char c = a&b; printf("%d", c);

ვინაიდან ბინარულ ფორმაში 3, როგორც ერთბაიტი მთელი რიცხვი წარმოადგენს

c ცვლადის პირველი ბიტი უდრის a რიცხვის პირველი ბიტის და b რიცხვის პირველი ბიტის ლოგიკურ ნამრავლს. და ასე შემდეგ ყოველი ბიტისთვის.

00000011
00001000
↓↓↓↓↓↓↓↓
00000000

შესაბამისად, 31 და 17 რიცხვების ბიტური ნამრავლი მისცემს 17-ს, რადგან 31 არის 00011111, ხოლო 17 არის 00010001.

00011111
00010001
↓↓↓↓↓↓↓↓
00010001

35 და 15 რიცხვების ბიტური ნამრავლი არის 3.

00100011
00001111
↓↓↓↓↓↓↓↓
00000011

Bitwise OR ოპერაცია (ოპერატორი |) მუშაობს ანალოგიურად, გარდა იმისა, რომ იგი ლოგიკურად აჯამებს რიცხვების შესაბამის ბიტებს გადატანის გარეშე.

მაგალითად,

Char a = 15; char b = 11; char c = a | ბ; printf("%d", c);

გამოვა 15, რადგან 15 არის 00001111 და 11 არის 00001011

00001111
00001011
↓↓↓↓↓↓↓↓
00001111

33-ისა და 11-ის ბიტვურში OR დააბრუნებს 43-ს, რადგან 33 არის 00100001 და 11 არის 00001011

00100001
00001011
↓↓↓↓↓↓↓↓
00101011

ბიტის უარყოფა (~ ოპერატორი) მუშაობს არა ერთ ბიტზე, არამედ მთელ რიცხვზე. ინვერსიის ოპერატორი ცვლის false-ს true-ში და true-ს false-ს თითოეული ბიტისთვის. მაგალითად,

Char a = 65; char b = ~a; printf("%d", b);

გამოვა -66, რადგან 65 არის 01000001, ხოლო ინვერსია მისცემს 10111110

რომელიც უდრის -66-ს. სხვათა შორის, აქ არის რიცხვის უარყოფითი მიღების ალგორითმი: რიცხვის დამატებითი კოდის საპოვნელად, თქვენ უნდა შეცვალოთ იგი და დაამატოთ ერთი.

Char a = 107; char b = ~a + 1; printf("a = %d, -a = %d", a, b);

ექსკლუზიური OR (^ ოპერატორი) იყენებს XOR ოპერაციას. მაგალითად, რიცხვებისთვის

Char a = 12; char b = 85; char c = a^b; printf("%d", c);

89 გამოვა, რადგან a არის 00001100 და b არის 01010101. შედეგად ვიღებთ 01011001

ზოგჯერ ლოგიკური ოპერატორები && და || დაბნეული & და |. ასეთი შეცდომები შეიძლება არსებობდეს კოდში საკმაოდ დიდი ხნის განმავლობაში, რადგან ასეთი კოდი ზოგიერთ შემთხვევაში იმუშავებს. მაგალითად, 1 და 0 რიცხვებისთვის. მაგრამ რადგან C-ში ნებისმიერი არა-ნულოვანი მნიშვნელობა მართალია, მაშინ 3 და 4 რიცხვების ბიტური გამრავლება უბრუნებს 0-ს, თუმცა ლოგიკური გამრავლება უნდა დაბრუნდეს true.

Int a = 3; int b = 4; printf("a & b = %d\n", a & b); //დაიბეჭდება 0 printf("a && b = %d\n", a && b);//დაიბეჭდება არა 0 (უფრო კონკრეტულად, 1)

ბიტის ცვლის ოპერაციები

არსებობს ორი ცვლის ოპერაცია - ბიტის ცვლა მარცხნივ (ოპერატორი<<) и битовый сдвиг вправо (оператор >>). Bit Shift მარჯვნივ გადაიტანს რიცხვის ბიტებს მარჯვნივ და მარცხნივ უმატებს ნულებს. Bit Shift მარცხნივ აკეთებს საპირისპიროს: ის ცვლის ბიტებს მარცხნივ და ამატებს ნულებს მარჯვნივ. ბიტები, რომლებიც აღემატება რაოდენობას, გაუქმებულია.

მაგალითად, გადაიტანეთ რიცხვი 5 მარცხნივ 2 პოზიციით

00000101 << 2 == 00010100

გადაიტანეთ ნომერი 19 მარჯვნივ 3 პოზიციით

00010011 >> 3 == 00000010

მიუხედავად არქიტექტურისა (დიდი-ენდიანი, ან მცირე-ენდიანი, ან შუა-ენდიანი), ორობითი რიცხვები წარმოდგენილია მარცხნიდან მარჯვნივ, ყველაზე მნიშვნელოვანი ბიტიდან ყველაზე ნაკლებად მნიშვნელოვანამდე. ბიტის ცვლას ორი ოპერანდი სჭირდება - გადასატანი რიცხვი და გადასატანი ბიტების რაოდენობა.

Int a = 12; printf("%d<< 1 == %d\n", a, a << 1); printf("%d << 2 == %d\n", a, a << 2); printf("%d >> 1 == %d\n", a, a >> 1); printf("%d >> 2 == %d\n", a, a >> 2);

ვინაიდან მარჯვენა ცვლა (>>) ამატებს ნულებს მარცხნივ, მთელი რიცხვებისთვის ოპერაცია უდრის მთელი რიცხვის გაყოფას ნახევარზე, ხოლო მარცხნივ ცვლა უდრის 2-ზე გამრავლებას. მცურავისთვის ბიტის ცვლის შესრულება შეუძლებელია. წერტილის ნომერი აშკარა ტიპის კასტის გარეშე. ეს იმიტომ ხდება, რომ C-ს არ აქვს მცურავი წერტილის წარმოდგენა განსაზღვრული. თუმცა, შეგიძლიათ float გადაიტანოთ int-ზე, შემდეგ გადაიტანოთ და დააბრუნოთ

ათწილადი b = 10.0f; float c = (float) (*((unsigned int*)&b) >> 2); printf("%.3f >> 2 = %.3f", b, c);

მაგრამ, რა თქმა უნდა, ჩვენ არ მივიღებთ 5.0f, არამედ სრულიად განსხვავებულ რიცხვს.

Shift ოპერატორების საქმე ის არის, რომ მათ შეუძლიათ განსხვავებულად მოიქცნენ ხელმოწერილი და ხელმოუწერელი ნომრებით, ეს დამოკიდებულია შემდგენელზე. მართლაც, უარყოფითი რიცხვი ჩვეულებრივ შეიცავს ერთი ნიშნის ბიტს. როდესაც მარცხნივ გადავინაცვლებთ, ის შეიძლება გაქრეს და რიცხვი დადებითი გახდეს. თუმცა, შემდგენელს შეუძლია ცვლა ნიშანში მუდმივი დარჩეს და სხვადასხვა წესების დაცვას. იგივე ეხება მარჯვნივ ცვლას.

ხელმოუწერელი int ua = 12; ხელმოწერილი int sa = -11; printf("ua = %d, ua >> 2 = %d\n", ua, ua >> 2); printf("sa = %d, sa >> 2 = %d\n", sa, sa >> 2); printf("(ხელმოუწერელი) sa = %u, sa >> 2 = %u\n", sa, sa >> 2); printf("sa = %d, ((ხელმოუწერელი) sa) >> 2 = %d", sa, ((ხელმოუწერელი) sa) >> 2);

ამ შემთხვევაში, პირველ ცვლაში ყველაფერი ისე მუშაობს, როგორც გათვალისწინებულია, რადგან ნომერი ხელმოუწერელია. მეორე შემთხვევაში, VSE2013 შემდგენელი ტოვებს ნიშანს. თუმცა, თუ შეხედავთ ამ რიცხვის წარმოდგენას, როგორც ხელმოუწერელად, ცვლა ხდება სხვადასხვა წესების მიხედვით, ხოლო მარცხენა ბიტი შენარჩუნებულია. ბოლო სტრიქონში თუ ხელმოწერილ რიცხვს გადავიყვანთ ხელმოუწერელ რიცხვად, მაშინ მოხდება ჩვეულებრივი ცვლა და შედეგად მივიღებთ დადებით რიცხვს.

Bitwise და shift ოპერატორები არ ცვლის რიცხვის მნიშვნელობას, აბრუნებენ ახალს. ისინი, ისევე როგორც არითმეტიკული ოპერატორები, შეიძლება იყოს რთული დავალების ნაწილი

Int a = 10; int b = 1; a >>= 3; a ^= (ბ<< 3); и т.д.

მაგალითები

1. დავწეროთ ფუნქციები, რომლებიც საშუალებას გაძლევთ განსაზღვროთ და შეცვალოთ რიცხვის გარკვეული ბიტი

იმისათვის, რომ გავიგოთ რომელი ბიტი (1 ან 0) არის n პოზიციაზე, ვიყენებთ ლოგიკურ გამრავლებას.

იყოს რიცხვი 9

00001001

ჩვენ უნდა გავარკვიოთ, არის თუ არა ბიტი დაყენებული მე-3 პოზიციაზე (დაწყებული ნულიდან). ამისათვის გაამრავლეთ ის რიცხვზე, რომლის ყველა ბიტი ნულია, გარდა მესამესა:

00001001 & 00001000 = 00001000

ახლა ჩვენ ვიგებთ ბიტის მნიშვნელობას მე-6 პოზიციაზე

00001001 & 01000000 = 00000000

ამრიგად, თუ მივიღებთ ნულის ტოლ პასუხს, მაშინ სასურველი პოზიცია არის ნული, წინააღმდეგ შემთხვევაში ერთი. იმისათვის, რომ მიიღოთ ნულისაგან შემდგარი რიცხვი ერთი ბიტით სასურველ მდგომარეობაში, გადაიტანეთ 1 ბიტის საჭირო რაოდენობის მიხედვით მარცხნივ.

#შეიცავს #შეიცავს #შეიცავს int checkbit(const int მნიშვნელობა, const int position) ( int შედეგი; if ((მნიშვნელობა & (1<< position)) == 0) { result = 0; } else { result = 1; } return result; } void main() { int a = 3; size_t len = sizeof(int) * CHAR_BIT; size_t i; for (i = 0; i < len; i++) { printf("%d", checkbit(a, i)); } _getch(); }

გაითვალისწინეთ, რომ ფუნქციაში მდგომარეობა ასე იწერება

(მნიშვნელობა & (1<< position)) == 0

რადგან ფრჩხილების გარეშე ჯერ გამოითვლება ნულის ტოლობა და მხოლოდ ამის შემდეგ შესრულდება გამრავლება.

მნიშვნელობა&(1<< position) == 0

ფუნქცია შეიძლება გამარტივდეს

Int checkbit(const int მნიშვნელობა, const int position) ( return ((მნიშვნელობა & (1<< position)) != 0); }

ფუნქცია, რომელიც აყენებს ბიტს n-ე პოზიციაზე ერთზე.

ცნობილია, რომ ნებისმიერი ბიტის ლოგიკური დამატება 1-თან იქნება 1-ის ტოლი. ასე რომ, n-ე ბიტის დასაყენებლად, ლოგიკურად უნდა დაამატოთ რიცხვი ერთთან, რომელშიც ყველა ბიტი საჭიროს გარდა ნულის ტოლია. როგორ მივიღოთ ასეთი ნომერი, უკვე განიხილეს.

Int setbit(const int მნიშვნელობა, const int position) (დაბრუნება (მნიშვნელობა | (1<< position)); }

ფუნქცია, რომელიც აყენებს ბიტს n-ე პოზიციაზე ნულამდე.

ამისათვის აუცილებელია, რომ რიცხვის ყველა ბიტი, გარდა n-ისა, უცვლელი დარჩეს. გავამრავლოთ რიცხვი ერთზე, რომელშიც ყველა ბიტი ერთის ტოლია, გარდა n ბიტისა. მაგალითად

0001011 & 1110111 = 0000011

ასეთი ნიღბის მისაღებად ჯერ ვქმნით რიცხვს ნულებით და ერთით და შემდეგ ვაბრუნებთ მას.

Int unsetbit (const int მნიშვნელობა, const int position) ( დაბრუნება (მნიშვნელობა & ~(1<< position)); }

ფუნქცია, რომელიც აბრუნებს n-ე ბიტის მნიშვნელობას.

ამისთვის გამოვიყენებთ ექსკლუზიურს ან ფუნქციას: გამოვიყენოთ XOR ოპერაცია რიცხვზე, რომელიც შედგება მხოლოდ ნულისაგან და ერთი ერთისაგან სასურველი ბიტის ნაცვლად.

Int switchbit(const int მნიშვნელობა, const int position) (დაბრუნება (მნიშვნელობა ^ (1<< position)); }

ექსპერტიზა

#შეიცავს #შეიცავს #შეიცავს int checkbit(const int მნიშვნელობა, const int position) ( return ((მნიშვნელობა & (1<< position)) != 0); } int setbit(const int value, const int position) { return (value | (1 << position)); } int unsetbit(const int value, const int position) { return (value & ~(1 << position)); } int switchbit(const int value, const int position) { return (value ^ (1 << position)); } void printbits(int n) { //CHAR_BIT опеределён в библиотеке limits.h //и хранит число бит в байте для данной платформы size_t len = sizeof(int)* CHAR_BIT; size_t i; for (i = 0; i < len; i++) { printf("%d", checkbit(n, i)); } printf("\n"); } void main() { int a = 3; size_t len = sizeof(int) * CHAR_BIT; size_t i; printbits(a); a = setbit(a, 5); printbits(a); a = unsetbit(a, 5); printbits(a); a = switchbit(a, 11); printbits(a); a = switchbit(a, 11); printbits(a); _getch(); }

ცოტა დროშები

მოდით შევხედოთ სინთეზურ მაგალითს. მოდით გვქონდეს სამი ლოგიკური ცვლადი და ჩვენ უნდა გამოვიტანოთ გარკვეული მნიშვნელობა ერთდროულად ყველა ამ ცვლადის მიხედვით. ცხადია, შეიძლება იყოს 2 ან 3 შესაძლო ვარიანტი. დავწეროთ ეს პირობა ტოტის სახით:

#შეიცავს int main() ( ხელმოუწერელი char a, b, c; a = 1; b = 0; c = 0; if (a) (if (b) (if (c) (printf("true true true"); ) else (printf("true true false"); ) ) else ( if (c) (printf ("true false true"); ) else (printf("true false false"); ) ) ) else (თუ (b) ( if (c) ( printf ("false false true"); ) else (printf("false true false"); ) ) else (if (c) (printf("false false true");) else (printf( "false false false");

მივიღეთ 8 ფილიალი. დავუშვათ, ახლა ჩვენ უნდა დავამატოთ კიდევ ერთი პირობა. შემდეგ ფილიალების რაოდენობა გაორმაგდება და პროგრამა კიდევ უფრო რთული გასაგები და გამართული გახდება. მოდით გადავწეროთ მაგალითი.

თუ თითოეული ჩვენი ლოგიკური მნიშვნელობა გადაინაცვლებს ბიტების რაოდენობის მიხედვით მარცხნივ და ლოგიკურად დაემატება, მაშინ მივიღებთ ბიტების ჩვენს უნიკალურ კომბინაციას a, b და c მნიშვნელობების მიხედვით:

#შეიცავს #შეიცავს ცარიელი ბეჭდვის ბიტები (int n) ( int i; for (i = CHAR_BIT - 1; i >= 0; i--) ( printf("%d", (n & (1<< i)) != 0); } printf("\n"); } int main() { unsigned char a, b, c; unsigned char res; a = 1; b = 0; c = 0; res = c | b << 1 | a << 2; printbits(res); a = 0; b = 1; c = 1; res = c | b << 1 | a << 2; printbits(res); a = 1; b = 0; c = 1; res = c | b << 1 | a << 2; printbits(res); _getch(); return 0; }

მოდით გამოვიყენოთ ეს მიდგომა ჩვენი პრობლემის მიმართ და შევცვალოთ განშტოება გადამრთველით:

#შეიცავს int main() ( unsigned char a, b, c; unsigned char res; a = 1; b = 0; c = 0; res = c | b<< 1 | a << 2; switch (res) { case 0b00000000: printf("false false false"); break; case 0b00000001: printf("false false true"); break; case 0b00000010: printf("false true false"); break; case 0b00000011: printf("false true true"); break; case 0b00000100: printf("true false false"); break; case 0b00000101: printf("true false true"); break; case 0b00000110: printf("true true false"); break; case 0b00000111: printf("true true true"); break; } _getch(); return 0; }

ეს მეთოდი ძალიან ხშირად გამოიყენება სხვადასხვა პროგრამირების ენაზე ფუნქციების ვარიანტების მინიჭებისთვის. თითოეული დროშა იღებს თავის უნიკალურ სახელს და მათი კომბინირებული მნიშვნელობა არის ყველა გამოყენებული დროშის ლოგიკური ჯამი. მაგალითად, fcntl ბიბლიოთეკა.

ფუნქცია, რომელსაც ისინი ასრულებენ, გარკვეულწილად უფრო რთულია, ვიდრე AND ელემენტის ან OR ელემენტის შემთხვევაში. XOR კარიბჭის ყველა შეყვანა თანაბარია, მაგრამ ვერც ერთი შეყვანა ვერ დაბლოკავს სხვა შეყვანას გამომავალი ერთზე ან ნულზე დაყენებით. ცხრილი 4.1. სიმართლის ცხრილიორი შეყვანის ექსკლუზიური OR ელემენტები
შეყვანა 1 შეყვანა 2 გასვლა
0 0 0
0 1 1
1 0 1
1 1 0


ბრინჯი. 4.1.

ექსკლუზიური OR ფუნქცია ნიშნავს შემდეგს: ერთი გამოჩნდება გამოსავალზე, როდესაც მხოლოდ ერთ შეყვანას აქვს ერთი. თუ შეყვანებზე ორი ან მეტია, ან თუ ყველა შეყვანა არის ნული, მაშინ გამომავალი იქნება ნული. სიმართლის ცხრილიორ შეყვანის ელემენტი Exclusive OR მოცემულია ცხრილში. 4.1. საშინაო და უცხოურ სქემებში მიღებული აღნიშვნები ნაჩვენებია ნახ. 4.1.

ელემენტის შიდა აღნიშვნაზე Exclusive OR "=1" წარწერა უბრალოდ ნიშნავს, რომ სიტუაცია ხაზგასმულია, როდესაც შეყვანებში არის ერთი და მხოლოდ ერთი ერთეული.

სტანდარტულ სერიაში რამდენიმე XOR ელემენტია. შიდა სერიები გვთავაზობენ LP5 მიკროსქემებს (ოთხი ორი შეყვანის ელემენტი 2C გამომავალი), LL3 და LP12, რომლებიც განსხვავდებიან LP5-ისგან OK გამომავალი. ზედმეტად სპეციფიკური ფუნქცია ხორციელდება ამ ელემენტებით.

მათემატიკური თვალსაზრისით, XOR კარიბჭე ასრულებს ეგრეთ წოდებულ მოდულო-2 შეჯამების ოპერაციას. როგორც წინა ლექციაში აღინიშნა, შემაჯამებელი მოდული 2 მითითებულია წრეში ჩასმული პლუსის ნიშნით. ელემენტების ძირითადი გამოყენება არის Exclusive OR, რომელიც პირდაპირ გამომდინარეობსსიმართლის ცხრილები , შედგება ორი შეყვანის სიგნალის შედარებისგან. იმ შემთხვევაში, როდესაც ორი ერთეული ან ორი ნული მოდის შეყვანებზე (სიგნალები ემთხვევა), გამომავალზე წარმოიქმნება ნული (იხ. ცხრილი 4.1). როგორც წესი, ამ აპლიკაციაში, მუდმივი დონე გამოიყენება ელემენტის ერთ შეყვანაზე, რომელთანაც შედარებულია დროში ცვალებადი სიგნალი, რომელიც მოდის სხვა შეყვანაში. მაგრამ ბევრად უფრო ხშირად, სპეციალური მიკროსქემები გამოიყენება სიგნალებისა და კოდების შესადარებლადკოდის შედარებები

, რაზეც მომდევნო ლექციაზე იქნება საუბარი.

როგორც modulo 2-ის შემკრები, XOR ელემენტი ასევე გამოიყენება პარალელურად და სერიული modulo 2 გამყოფები გამოიყენება ციკლური გამშვები ჯამების გამოსათვლელად. მაგრამ ეს სქემები დეტალურად იქნება განხილული ლექციებში 14,15. XOR ელემენტების მნიშვნელოვანი გამოყენებაა კონტროლირებადი ინვერტორი (ნახ. 4.2).ამ შემთხვევაში, ელემენტის ერთ-ერთი შეყვანა გამოიყენება როგორც საკონტროლო, ხოლო საინფორმაციო სიგნალი მიიღება ელემენტის მეორე შესასვლელში. თუ საკონტროლო შეყვანა არის ერთი, მაშინ შეყვანის სიგნალი ინვერსიულია, მაგრამ თუ ის ნულია, ის არ არის ინვერსიული. უფრო ხშირად საკონტროლო სიგნალი.


ბრინჯი. 4.2.

იმ შემთხვევაში, როდესაც არსებობს ორი ერთი და იგივე პოლარობის სიგნალი (დადებითი ან უარყოფითი), და მათი ერთდროული ჩამოსვლა გამორიცხულია, ამ სიგნალების შერევისთვის შეიძლება გამოყენებულ იქნას Exclusive OR ელემენტი (ნახ. 4.3). შეყვანის სიგნალების ნებისმიერი პოლარობისთვის, ელემენტის გამომავალი სიგნალები დადებითი იქნება. დადებითი შეყვანის სიგნალებისთვის, XOR კარიბჭე იმოქმედებს როგორც 2OR კარიბჭე, ხოლო უარყოფითი შეყვანისთვის, ის შეცვლის 2AND-NOT კარიბჭეს. ასეთი ჩანაცვლება შეიძლება სასარგებლო იყოს იმ შემთხვევებში, როდესაც ზოგიერთი Exclusive OR ელემენტი რჩება გამოუყენებელი წრეში. მართალია, გასათვალისწინებელია, რომ გამრავლების შეფერხება XOR ელემენტში სიგნალი ჩვეულებრივ ოდნავ აღემატება (დაახლოებით 1,5-ჯერ) ვიდრე შეფერხება უმარტივეს AND, NAND, OR, NOR ელემენტებში.

XOR ინსტრუქცია ასამბლეის ენაზე ასრულებს ექსკლუზიურ OR ოპერაციას ორი ოპერანდის ყველა ბიტს შორის. XOR ოპერაციის შედეგი იწერება პირველ ოპერანდზე. სინტაქსი:

XOR მიმღები, წყარო

XOR ინსტრუქცია ყოველთვის აღადგენს CF და OF-ს და ასევე (შედეგიდან გამომდინარე) ცვლის SF, ZF და PF დროშებს. AF დროშის მნიშვნელობა შეიძლება იყოს ნებისმიერი - ეს არ არის დამოკიდებული ოპერაციის შედეგზე.

RECEIVER შეიძლება იყოს ერთ-ერთი შემდეგი:

  • მეხსიერების არე (MEM)

SOURCE შეიძლება იყოს ერთ-ერთი შემდეგი:

  • მეხსიერების არე (MEM)
  • ზოგადი დანიშნულების რეესტრი (REG)
  • დაუყოვნებელი მნიშვნელობა - მუდმივი (IMM)

ზემოთ აღწერილი შეზღუდვების გათვალისწინებით, RECEIVER-SOURCE კომბინაციები შეიძლება იყოს შემდეგი:

REG, MEM MEM, REG REG, REG MEM, IMM REG, IMM

ექსკლუზიური OR ოპერაცია

ექსკლუზიური OR ოპერაციის შესრულებისას, შედეგის მნიშვნელობა იქნება 1, თუ შედარებული ბიტები განსხვავებულია (არა ტოლი). თუ შედარებულ ბიტებს აქვთ იგივე მნიშვნელობა, მაშინ შედეგი იქნება 0.

ამიტომ ამ ოპერაციას ექსკლუზიური ეწოდება. ის გამორიცხავს იდენტურ ბიტებს შედარებიდან და ასრულებს ოპერაციას არათანაბარ ბიტებზე.

მაგრამ, რადგან ნებისმიერი წყვილი არათანაბარი ბიტი არის 0 და 1, ლოგიკური OR ოპერაცია გამოიწვევს 1-ს.

ექსკლუზიური ან სიმართლის ცხრილი

XOR სიმართლის ცხრილი მოცემულია ქვემოთ:

0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0

XOR ოპერაციის მახასიათებლები

XOR ოპერაციას აქვს შექცევადობის თვისება. თუ ის ორჯერ შესრულდება ერთი და იგივე ოპერანდით, შედეგის მნიშვნელობა ინვერსიულია. ანუ თუ ამ ოპერაციას ორჯერ შეასრულებ ბიტებს შორის Xდა , შემდეგ საბოლოო შედეგში მივიღებთ ორიგინალური ბიტის მნიშვნელობას X.

0 XOR 0 = 0 XOR 0 = 0 0 XOR 1 = 1 XOR 1 = 0 1 XOR 0 = 1 XOR 0 = 1 1 XOR 1 = 0 XOR 1 = 1

ეს თვისება შეიძლება გამოყენებულ იქნას, მაგალითად, მონაცემთა მარტივი დაშიფვრისთვის (დაწვრილებით სხვა დროს).

XOR ოპერაციის შემდეგ პარიტეტის დროშის შემოწმება

XOR ბრძანება მუშაობს 8-, 16- და 32-ბიტიანი ოპერაციებით.

ზოგჯერ საჭიროა ოპერაციის შესრულების შემდეგ შეამოწმოთ პარიტეტის დროშა PF, რათა გაიგოთ რამდენი ერთეული ბიტი (ლუწი ან კენტი) შეიცავს დაბალი ბაიტიშედეგი (ეს აუცილებელია არა მხოლოდ XOR ოპერაციის შესრულებისას, არამედ სხვა არითმეტიკული და ლოგიკური ოპერაციების შესრულებისას).

თუ პარიტეტის დროშა დაყენებულია, შედეგი არის ერთი ბიტის ლუწი რიცხვი. წინააღმდეგ შემთხვევაში დროშა აღდგება.

თქვენ ასევე შეგიძლიათ უბრალოდ შეამოწმოთ ნებისმიერი რიცხვი პარიტეტისთვის, შედეგის მნიშვნელობის შეცვლის გარეშე. ამისათვის თქვენ უნდა შეასრულოთ XOR ბრძანება ნულოვანი მნიშვნელობით. ანუ, RECEIVER უნდა შეიცავდეს შესამოწმებელ რიცხვს, ხოლო SOURCE უნდა შეიცავდეს ნულს. და შემდეგ თქვენ უნდა შეამოწმოთ პარიტეტის დროშა. მაგალითი:

AL, 10110101b ;AL-ში მოათავსეთ კენტი რიცხვი;ერთი ბიტის რიცხვი (5) XOR AL, 0 ;ამ შემთხვევაში, პარიტეტის დროშა PF არ არის; დაყენებული (PO) MOV AL, 10110111b ;განათავსეთ AL რიცხვში ლუწი;ერთი ბიტის რაოდენობა (6) XOR AL, 0 ;ამ შემთხვევაში, პარიტეტის დროშა PF ; დაყენდება (PE)

გამართულებში, აბრევიატურა PE (Parity Even) ჩვეულებრივ გამოიყენება მიღებულ შედეგში ლუწი რიცხვის აღსანიშნავად, ხოლო კენტი რიცხვისთვის PO (Parity Odd).

პარიტეტი 16-ბიტიან სიტყვებში

როგორც უკვე აღვნიშნეთ, პარიტეტის დროშა დაყენებულია შედეგის დაბალ ბაიტში შემავალი ერთეულების რაოდენობის მიხედვით. 16-ბიტიანი ოპერანდის პარიტეტის შესამოწმებლად, თქვენ უნდა XOR შეადგინოთ რიცხვის მაღალი და დაბალი ბაიტი:

MOV AX, 64C1h ;0110 0100 1100 0001 - 6 ერთი ბიტი XOR AH, AL ; დაყენდება პარიტეტის დროშა

ამ მარტივი გზით, 16-ბიტიანი ოპერანდი იყოფა ორ ბაიტად (2 ჯგუფი 8-ბიტიანი) და XOR ბრძანების შესრულებისას, ორი 8-ბიტიანი ოპერანდის შესაბამის ბიტებში მდებარე ერთი ბიტი არ იქნება აღებული. ანგარიში. რადგან შედეგის შესაბამისი ბიტი არის ნული.

XOR ინსტრუქცია შლის შედეგს ორი 8-ბიტიანი ოპერანდის ნებისმიერ გადახურულ ერთ ბიტს და შედეგს უმატებს ერთ ბიტს. ანუ, ჩვენ მიერ მიღებული 8-ბიტიანი ნომრის პარიტეტი იქნება იგივე, რაც ორიგინალური 16-ბიტიანი ნომრის პარიტეტი.

0110 0100 1100 0001 - ორიგინალი 16-ბიტიანი ნომერი 0 XOR 1 = 1 1 XOR 1 = 0 1 XOR 0 = 1 0 XOR 0 = 0 0 XOR 0 = 0 1 XOR 0 = 1 0 XOR 0 = 0 0 XOR 1 = 1

შედეგი არის 4 ერთეული, ანუ დაყენდება PF დროშა

პარიტეტი 32-ბიტიან ორმაგ სიტყვებში

რა მოხდება, თუ გჭირდებათ 32-ბიტიანი ნომრის პარიტეტის დადგენა?

შემდეგ რიცხვი იყოფა ოთხ ბაიტად და ამ ბაიტებზე სათითაოდ შესრულებულია ექსკლუზიური OR ოპერაცია.

მაგალითად, ჩვენ ვყოფთ 32-ბიტიან რიცხვს ოთხი ბაიტით B0, B1, B2, B3, სად B0- ეს არის დაბალი ბაიტი.

შემდეგ B რიცხვის პარიტეტის დასადგენად, დაგვჭირდება შემდეგი ფორმულის გამოყენება:

B0 XOR B1 XOR B2 XOR B3

მაგრამ ასამბლერში ასეთი აღნიშვნა დაუშვებელია. ამიტომ ცოტა დაფიქრება მოგიწევთ.

და ბოლოს, მნემონიკის წარმოშობის შესახებ არა. ინგლისურად არის სიტყვა ე Xმიღება - გამონაკლისი. ამ სიტყვის აბრევიატურა არის ასო X(ასე მოხდა). თქვენ ალბათ გინახავთ ეს რეკლამაში ან იმ პროდუქტების სახელებში, რომელთა მწარმოებლები აცხადებენ (ან ფიქრობენ, რომ ისინი აცხადებენ) ექსკლუზიურობას. მაგალითად, Lada XRAY, Sony XPeria და ა.შ. ასე რომ, XOR არის აკრონიმი, რომელიც შედგება ორი სიტყვისგან - ე Xმიღება და- ექსკლუზიური OR.