ทำไมตัวเลขฐานสิบหกนำหน้าด้วย 0x


414

ทำไมตัวเลขฐานสิบหกเป็นคำนำหน้า0x? ฉันเข้าใจการใช้คำนำหน้า แต่ฉันไม่เข้าใจความสำคัญของสาเหตุที่0xเลือก


9
ตอนนี้ฉันรู้แล้วว่าชื่อและข้อความถามคำถามสองข้อที่แตกต่างกันอย่างสิ้นเชิง คำตอบส่วนใหญ่มุ่งเน้นไปที่คำถามในชื่อเรื่อง คำตอบของคำถามในข้อความเป็นเพียง "มันไม่ได้หมายความว่าอะไร - มันเป็นเพียงคำนำหน้าบอกคอมไพเลอร์ว่าจำนวนเต็มเขียนเป็นเลขฐานสิบหก"
Andreas Rejbrand

30
เพื่อเป็นการหยั่งรู้คนหนึ่งอาจตีความคำถามในหัวเรื่องด้วยสองวิธีที่แตกต่างกัน: 1) "ทำไมตัวเลขฐานสิบหกนำหน้าด้วย 0x เมื่อเทียบกับคำนำหน้าหรือตัวบ่งชี้อื่น ๆ " 2) "ทำไมเราต้องใช้คำนำหน้าเมื่อป้อนเลขฐานสิบหกแน่นอนผู้แปลจะจำ 58A เป็นเลขฐานสิบหกแม้ไม่มีคำนำหน้า" คำตอบสำหรับการตีความที่สองของคำถามนั้นเล็กน้อย "123" เป็นตัวเลขฐานสิบหก
Andreas Rejbrand

คำตอบ:


440

เรื่องสั้น: The 0บอก parser ว่ามันเกี่ยวข้องกับค่าคงที่ ยังคงมีบางสิ่งที่จำเป็นต้องระบุฐานจำนวน: xตัวเลือกนี้เป็นตัวเลือก

เรื่องยาว:ในยุค 60 ระบบหมายเลขการเขียนโปรแกรมที่แพร่หลายเป็นทศนิยมและฐานแปด - เมนเฟรมมี 12, 24 หรือ 36 บิตต่อไบต์ซึ่งสามารถหารได้อย่างสวยงามโดย 3 = log2 (8)

ภาษา BCPL ใช้ไวยากรณ์8 1234สำหรับตัวเลขฐานแปด เมื่อ Ken Thompson สร้าง B จาก BCPL เขาใช้0คำนำหน้าแทน อันนี้ยอดเยี่ยมเพราะ

  1. ค่าคงที่จำนวนเต็มในขณะนี้ประกอบด้วยโทเค็นเดียวเสมอ
  2. ตัวแยกวิเคราะห์สามารถบอกได้ทันทีว่ามันมีค่าคงที่
  3. โปรแกรมแยกวิเคราะห์สามารถบอกฐานได้ทันที ( 0เหมือนกันทั้งสองฐาน)
  4. มันมีเหตุผลทางคณิตศาสตร์ ( 00005 == 05) และ
  5. ไม่จำเป็นต้องใช้อักขระพิเศษอันมีค่า (ดังใน#123)

เมื่อ C ถูกสร้างขึ้นจาก B ความต้องการเลขฐานสิบหกก็เกิดขึ้น (PDP-11 มีคำ 16 บิต) และคะแนนทั้งหมดข้างต้นยังคงใช้ได้ ตั้งแต่ octals ก็ยังคงจำเป็นสำหรับเครื่องอื่น ๆ0xได้รับการแต่งตั้งโดยพล ( 00อาจจะถูกตัดออกเป็นที่น่าอึดอัดใจ)

C # เป็นผู้สืบทอดของ C ดังนั้นมันจึงสืบทอดไวยากรณ์


112
ฉันไม่คิดว่า0xมากกว่า00นั้นคือความชอบ / ความอึดอัดใจ 00จะทำลายรหัสที่มีอยู่ 0010เป็นฐานแปดคือ8ในขณะที่0010เป็น hexidecimal 16จะเป็น พวกเขาไม่สามารถใช้ตัวเลขใด ๆ เป็นตัวบ่งชี้ตัวเลขหลักที่สอง (ยกเว้น8หรือ9และไม่มีความสำคัญใด ๆ ที่เกี่ยวข้องกับเลขฐานสิบหก) ดังนั้นจึงต้องมีจดหมาย และนั่นก็ทิ้งไว้0hหรือ0x( h e X idecimal) จากจุดนี้ดูเหมือนว่าจะกลับไปที่การตั้งค่าอย่างแท้จริง
GManNickG


23
การใช้0คำนำหน้าสำหรับเลขฐานแปดทำให้เกิดปัญหามากมายในช่วงหลายปีที่ผ่านมา 0โดยเฉพาะอย่างยิ่งในประเทศเช่นสหราชอาณาจักรที่หมายเลขโทรศัพท์เริ่มต้นด้วย Javascript และภาษาอื่น ๆ จะแยกวิเคราะห์สิ่งเหล่านี้เป็นฐานแปด, mangling หมายเลขก่อนที่จะจัดเก็บ เพื่อเพิ่มความสนุกสนานผลิตภัณฑ์ฐานข้อมูลหนึ่งที่เป็นที่นิยมจะเงียบสลับกลับไปแยกทศนิยมถ้าจำนวนที่มีอยู่หรือ8 9
พื้นฐาน

1
12, 24 และ 36 หารด้วย 4 ด้วยเหตุใดพวกเขาจึงไม่คิดเลขฐานสิบหกสำหรับสิ่งนั้น
phuclv

4
@ LưuVĩnhPhúcอาจเป็นเพราะเลขฐานสิบหกไม่เกี่ยวข้องกันมาก ส่วนใหญ่ของฮาร์ดแวร์ซอฟต์แวร์และเอกสารประกอบของเวลานั้นมีค่าฐานแปดที่ดีกว่ามาก BCPL เริ่มใช้ครั้งแรกบนIBM 7094 บิตขนาด 36 บิตโดยมีรูปแบบการสอนแบ่งออกเป็นสองส่วน 3 บิตและ 2 15 บิตส่วน อักขระ 6 บิต และเอกสารเป็นฐานแปด การใช้งานในช่วงต้นของ B นั้นอยู่ใน PDP-7 (18 บิต) และ Honeywell GE-945 (36 บิต แต่มีการกำหนดแอดเดรส 18 บิตและรองรับ 6 และ 9 บิตไบต์) PDP-11 16 บิตออกมาหลังจาก B ดังนั้นจะไม่มีอิทธิพลต่อการออกแบบของ B มากนัก
8bittree

97

หมายเหตุ: ฉันไม่ทราบคำตอบที่ถูกต้อง แต่ด้านล่างเป็นเพียงการเก็งกำไรส่วนตัวของฉัน!

ตามที่ได้รับการกล่าวถึง 0 ก่อนจำนวนหมายความว่ามันเป็นเลขฐานแปด:

04524 // octal, leading 0

ลองนึกภาพว่าจำเป็นต้องมีระบบเพื่อแสดงตัวเลขฐานสิบหกและสังเกตว่าเรากำลังทำงานในสภาพแวดล้อมสไตล์ C วิธีจบด้วย h เช่นการประกอบ? น่าเสียดายที่คุณทำไม่ได้ - มันจะช่วยให้คุณทำโทเค็นซึ่งเป็นตัวระบุที่ถูกต้อง (เช่นคุณสามารถตั้งชื่อตัวแปรแบบเดียวกัน) ซึ่งจะทำให้เกิดความกำกวมที่น่ารังเกียจ

8000h // hex
FF00h // oops - valid identifier!  Hex or a variable or type named FF00h?

คุณไม่สามารถนำตัวละครด้วยเหตุผลเดียวกัน:

xFF00 // also valid identifier

การใช้แฮชอาจถูกโยนออกไปเพราะขัดแย้งกับตัวประมวลผลล่วงหน้า:

#define ...
#FF00 // invalid preprocessor token?

ในท้ายที่สุดไม่ว่าจะด้วยเหตุผลใดพวกเขาตัดสินใจที่จะวาง x หลังค่านำ 0 เพื่อแสดงเลขฐานสิบหก มันไม่คลุมเครือเนื่องจากมันยังคงขึ้นต้นด้วยตัวอักษรตัวเลขดังนั้นจึงไม่สามารถเป็นตัวระบุที่ถูกต้องและอาจเป็นไปตามอนุสัญญาฐานแปดของ 0 นำหน้า

0xFF00 // definitely not an identifier!

3
น่าสนใจ ฉันคิดว่าพวกเขาอาจใช้ 0 นำหน้าและลากท้าย h เพื่อแสดงเลขฐานสิบหก h ต่อท้ายอาจจะสับสนกับคำต่อท้ายตัวระบุประเภทเช่น 0xFF00l เทียบกับ 0FF00hl
zdan

2
อาร์กิวเมนต์นี้บอกเป็นนัยว่าการใช้ศูนย์นำหน้าเพื่อแสดงถึงจำนวนฐานแปดนำหน้าการใช้คำนำหน้าเลขฐานสิบหก "0x" มันเป็นเรื่องจริงเหรอ?
Andreas Rejbrand

1
พวกเขาจะไม่ถูกประดิษฐ์ทั้งสองในเวลาเดียวกัน? ทำไมจะมี แต่ไม่อื่น
AshleysBrain

AshleysBrain ดูคำตอบโดย @ Řrřolaสำหรับสาเหตุที่อาจมีเลขฐานแปด แต่ไม่ใช่เลขฐานสิบหกในเวลาเดียวกัน
jv42

2
@zdan พวกเขาใช้มันมานานแล้ว ในแอสเซมบลีของ Intel x86 ตัวอักษรฐานสิบหกต้องนำหน้าด้วย 0 เสมอหากเริ่มต้นด้วยอักขระ ยกตัวอย่างเช่นจะต้องเขียนเป็น0xFFAB1234 0FFAB1234hฉันจำได้จาก inline asm ใน Pascal เมื่อฉันเป็นstackoverflow.com/q/11733731/995714
phuclv

27

มันเป็นคำนำหน้าเพื่อระบุจำนวนที่เป็นเลขฐานสิบหกมากกว่าในฐานอื่น ๆ ภาษาการเขียนโปรแกรม C ใช้เพื่อบอกคอมไพเลอร์

ตัวอย่าง:

0x6400แปลว่า 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. เมื่อคอมไพเลอร์อ่าน0x6400มันเข้าใจว่าจำนวนเป็นเลขฐานสิบหกด้วยความช่วยเหลือของ คำ0x โดยปกติเราสามารถเข้าใจโดย (6400) 16หรือ (6400) 8หรืออะไรก็ได้ ..

สำหรับไบนารีมันจะเป็น:

0b00000001

หวังว่าฉันได้ช่วยในทางใดทางหนึ่ง

ขอให้เป็นวันที่ดี!


2
ตัวอักษรไบนารีได้รับการสนับสนุนเฉพาะใน C ++ ตั้งแต่ C ++ 14 และไม่รองรับใน C เลย
Ruslan

1
นี้ไม่ได้อธิบายว่าทำไม โดยเฉพาะทำไมคุณไม่เขียนตัวอย่างแรกเป็นx6400? xยังสามารถนำมาใช้เพื่อสรุปเลขฐานสิบหก
Aaron Franke

12

0 ก่อนหน้านี้ใช้เพื่อระบุตัวเลขในฐาน 2, 8, หรือ 16

ในความคิดของฉัน 0x ได้รับเลือกให้ระบุเลขฐานสิบหกเพราะ 'x' ดูเหมือนเป็นเลขฐานสิบหก

แค่ความเห็นของฉัน แต่ฉันคิดว่ามันสมเหตุสมผล

ขอให้เป็นวันที่ดี!


2
ขอบคุณสำหรับคำตอบ! ฉันเข้าใจว่านี่เป็นโพสต์แรกของคุณใน StackOverflow คำตอบอาจมีประโยชน์มากกว่านี้หากความคิดเห็นแยกจากข้อเท็จจริง
vivek_ganesan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.