ควรหลีกเลี่ยง <= และ> = เมื่อใช้จำนวนเต็มเช่นในวง For หรือไม่ [ปิด]


15

ฉันอธิบายให้นักเรียนฟังว่าการทดสอบที่เท่ากันไม่น่าเชื่อถือสำหรับตัวแปรลอยตัว แต่ใช้ได้สำหรับจำนวนเต็ม หนังสือที่ฉันใช้บอกว่าง่ายต่อการอ่าน> และ <กว่า> = และ <= ฉันเห็นด้วยบ้าง แต่ใน For For? ไม่ชัดเจนว่าการวนซ้ำระบุค่าเริ่มต้นและสิ้นสุดหรือไม่

ฉันไม่มีสิ่งที่ผู้เขียนตำราเรียนถูกต้องหรือไม่?

อีกตัวอย่างหนึ่งคือในการทดสอบช่วงเช่น:

ถ้าคะแนน> 89 grade = 'A'
อื่นถ้าคะแนน> 79 grade = 'B' ...

ทำไมไม่พูดเพียงว่า: if score> = 90?

loops 

11
น่าเสียดายที่เนื่องจากไม่มีความแตกต่างอย่างมีวัตถุประสงค์ในพฤติกรรมระหว่างตัวเลือกเหล่านี้จำนวนนี้สำหรับการสำรวจความคิดเห็นเกี่ยวกับสิ่งที่ผู้คนพิจารณาว่าใช้งานง่ายกว่าและการสำรวจไม่เหมาะสำหรับไซต์ StackExchange เช่นนี้
Ixrec

1
มันไม่สำคัญ จริงๆ.
Auberon

4
จริงๆแล้วนี่เป็นคำตอบที่เป็นกลาง สนับสนุน ...
Robert Harvey

9
@Ixrec ฉันมักจะพบว่าน่าสนใจว่า "แนวปฏิบัติที่ดีที่สุด" ไม่ถือว่าเป็นหัวข้อที่เหมาะสม ใครที่ไม่ต้องการปรับปรุงหรือทำให้โค้ดอ่านง่ายขึ้น หากผู้คนไม่เห็นด้วยเราทุกคนเรียนรู้เรื่องต่าง ๆ มากขึ้นและอาจ ... แม้กระทั่ง ... เปลี่ยนความคิดของเรา! อืมมันยากที่จะพูด Robert Harvey กล่าวว่าเขาสามารถตอบได้อย่างเป็นกลาง มันจะน่าสนใจ

1
@nocomprende ส่วนใหญ่เป็นเพราะ "วิธีปฏิบัติที่ดีที่สุด" เป็นคำที่คลุมเครือและใช้มากเกินไปซึ่งสามารถอ้างถึงคำแนะนำที่เป็นประโยชน์ตามข้อเท็จจริงเกี่ยวกับภาษา แต่มักจะหมายถึง "ความนิยมสูงสุด" (หรือความคิดเห็นของใครก็ตามที่ใช้คำนี้) เมื่อในความเป็นจริงตัวเลือกทั้งหมดมีความถูกต้องและไม่ถูกต้องเท่ากัน ในกรณีนี้คุณสามารถโต้แย้งได้โดยการ จำกัด คำตอบของลูปบางประเภทอย่างที่โรเบิร์ตทำและในขณะที่คุณชี้ให้เห็นความคิดเห็นที่ไม่ตอบคำถามอย่างสมบูรณ์
Ixrec

คำตอบ:


36

ในภาษาการเขียนโปรแกรมแบบหยิกที่มีอาร์เรย์เป็นศูนย์มันเป็นธรรมเนียมในการเขียนforลูปดังนี้:

for (int i = 0; i < array.Length, i++) { }

สิ่งนี้จะสำรวจองค์ประกอบทั้งหมดในอาเรย์และเป็นกรณีที่พบได้บ่อยที่สุด มันหลีกเลี่ยงการใช้หรือ<=>=

เวลาเดียวที่จะต้องเปลี่ยนคือเมื่อคุณต้องการข้ามองค์ประกอบแรกหรือสุดท้ายหรือข้ามไปในทิศทางตรงกันข้ามหรือข้ามจากจุดเริ่มต้นที่แตกต่างกันหรือจุดสิ้นสุดที่แตกต่างกัน

สำหรับคอลเลกชันในภาษาที่รองรับตัววนซ้ำมันเป็นเรื่องธรรมดามากที่จะเห็นสิ่งนี้:

foreach (var item in list) { }

ซึ่งหลีกเลี่ยงการเปรียบเทียบทั้งหมด

หากคุณกำลังมองหากฎอย่างหนักและรวดเร็วว่าจะใช้<=กับ vs ได้เมื่อไหร่<ก็ไม่มี ใช้สิ่งที่บ่งบอกความตั้งใจของคุณได้ดีที่สุด หากรหัสของคุณต้องการที่จะแสดงแนวคิด "น้อยกว่าหรือเท่ากับ 55 ไมล์ต่อชั่วโมง" แล้วก็ต้องบอกว่าไม่<=<

เพื่อตอบคำถามของคุณเกี่ยวกับช่วงเกรด>= 90ให้เหมาะสมกว่าเนื่องจาก 90 เป็นค่าขอบเขตจริงไม่ใช่ 89


9
มันไม่ได้หลีกเลี่ยงการเปรียบเทียบทั้งหมดมันแค่กวาดพวกมันใต้พรมปูพื้น : P
Mason Wheeler

2
แน่นอน แต่นั่นไม่ใช่การสำรวจอาร์เรย์อีกต่อไปใช่ไหม
Robert Harvey

4
เพราะอาร์เรย์เป็นกรณีที่ใช้งานบ่อยที่สุดสำหรับforลูปเช่นนี้ รูปแบบของการforวนซ้ำที่ฉันให้ไว้ที่นี่จะเป็นที่จดจำได้ทันทีสำหรับนักพัฒนาที่มีประสบการณ์จำนวนเล็กน้อย หากคุณต้องการคำตอบที่เฉพาะเจาะจงมากขึ้นตามสถานการณ์ที่เฉพาะเจาะจงมากขึ้นคุณจะต้องรวมคำถามนั้นไว้ในคำถามของคุณด้วย
Robert Harvey

3
"ใช้สิ่งที่แสดงออกถึงเจตนาของคุณได้ดีที่สุด" <- อันนี้!
Jasper N. Brouwer

3
@ JasperN.Brouwer มันเหมือนกฎของการเขียนโปรแกรมซีโรท กฎสไตล์ทั้งหมดและแบบแผนการเข้ารหัสล้มเหลวอย่างน่าละอายที่สุดเมื่อเอกสารของพวกเขาขัดแย้งกับความชัดเจนของรหัส
Iwillnotexist Idonotexist

16

มันไม่สำคัญ

แต่เพื่อประโยชน์ของการโต้แย้งขอวิเคราะห์สองตัวเลือก: VSa > ba >= b

รอก่อน! นั่นไม่เท่ากัน!
OK แล้วa >= b -1VS a > bหรือเทียบa > ba >= b +1

หืมมมa >bและa >= bดูทั้งที่ดีกว่าและa >= b - 1 a >= b +1สิ่งเหล่านี้1คืออะไรกันล่ะ? ดังนั้นผมจึงต้องการยืนยันว่าผลประโยชน์ใด ๆ จากการมี>แทน>=หรือในทางกลับกันจะถูกกำจัดออกโดยไม่ต้องเพิ่มหรือลบสุ่ม1s

แต่ถ้าเป็นตัวเลขล่ะ จะดีกว่าที่จะพูดa > 7หรือa >= 6? รอสักครู่. เรากำลังเถียงอย่างจริงจังหรือไม่ว่าจะเป็นการดีกว่าที่จะใช้>vs >=และไม่สนใจตัวแปรฮาร์ดโค้ด ดังนั้นมันจึงกลายเป็นคำถามที่ว่าa > DAYS_OF_WEEKดีกว่าa >= DAYS_OF_WEEK_MINUS_ONE... หรือว่าจะเป็นa > NUMBER_OF_LEGS_IN_INSECT_PLUS_ONEvs a >= NUMBER_OF_LEGS_IN_INSECT? และเรากลับไปที่การเพิ่ม / ลบ1s เพียงครั้งนี้ในชื่อตัวแปร หรืออาจโต้วาทีหากเป็นการดีที่สุดที่จะใช้ขีด จำกัด ขีด จำกัด สูงสุด

และดูเหมือนว่าไม่มีกฎทั่วไป: ขึ้นอยู่กับสิ่งที่ถูกเปรียบเทียบ

แต่จริงๆแล้วมีสิ่งที่สำคัญกว่ามากในการปรับปรุงโค้ดและแนวทางที่มีวัตถุประสงค์และสมเหตุสมผล (เช่นขีด จำกัด อักขระ X ต่อบรรทัด) ที่ยังคงมีข้อยกเว้น


1
ตกลงไม่มีกฎทั่วไป (สงสัยว่าทำไมหนังสือเรียนถึงได้ระบุกฎทั่วไป แต่ฉันสามารถปล่อยมันไปได้) ไม่มีความเห็นเป็นเอกฉันท์ว่าเป็นบันทึกที่ฉันพลาดไป

2
@nocomprende เพราะมาตรฐานการเข้ารหัสและการจัดรูปแบบมีทั้งแบบอัตนัยและเป็นที่ถกเถียงกันอย่างมาก ส่วนใหญ่ไม่มีใครมีความสำคัญ แต่โปรแกรมเมอร์ยังคงทำสงครามศักดิ์สิทธิ์อยู่เหนือพวกเขา (พวกเขามีความสำคัญก็ต่อเมื่อโค้ดเลอะเทอะมีแนวโน้มที่จะทำให้เกิดข้อผิดพลาด)

1
ฉันเคยเห็นการถกเถียงกันอย่างบ้าคลั่งมากมายเกี่ยวกับมาตรฐานการเข้ารหัส แต่อันนี้อาจต้องใช้เค้ก โง่จริงๆ
JimmyJames

@JimmyJames เกี่ยวกับการอภิปรายของ>vs >=หรือการอภิปรายเกี่ยวกับว่าการสนทนาของ>vs >=มีความหมายหรือไม่ แม้ว่าอาจเป็นเรื่องที่ดีที่สุดที่จะหลีกเลี่ยงการพูดคุยเรื่องนี้: p
Thanos Tintinidis

2
“ โปรแกรมมีไว้เพื่อให้มนุษย์อ่านได้และมีเพียงเครื่องคอมพิวเตอร์เท่านั้นที่จะดำเนินการ” - Donald Knuth ใช้สไตล์ที่ทำให้อ่านเข้าใจและบำรุงรักษาได้ง่ายที่สุด
simpleuser

7

คอมพิวเตอร์มีความแตกต่างในค่าใช้จ่ายเมื่อใช้ไม่มี<หรือ>เมื่อเทียบกับหรือ<= >=มันคำนวณเร็วพอ ๆ กัน

อย่างไรก็ตามลูปส่วนใหญ่จะนับจาก 0 (เนื่องจากหลายภาษาใช้ 0 การจัดทำดัชนีสำหรับอาร์เรย์) ดังนั้นบัญญัติสำหรับห่วงในภาษาเหล่านั้นคือ

for(int i = 0; i < length; i++){
   array[i] = //...
   //...
}

การทำเช่นนี้กับ a <=จะทำให้คุณต้องเพิ่ม -1 ที่ไหนสักแห่งเพื่อหลีกเลี่ยงข้อผิดพลาดที่ละครั้ง

for(int i = 1; i <= length; i++){
   array[i-1] = //...
   //...
}

หรือ

for(int i = 0; i <= length-1; i++){
   array[i] = //...
   //...
}

แน่นอนว่าหากภาษานั้นใช้การจัดทำดัชนีแบบ 1 ครั้งคุณจะต้องใช้ <= เป็นเงื่อนไขการ จำกัด

คีย์คือค่าที่แสดงในเงื่อนไขนั้นเป็นค่าที่มาจากคำอธิบายปัญหา มันอ่านง่ายกว่า

if(x >= 10 && x < 20){

} else if(x >= 20 && x < 30){

}

สำหรับช่วงเปิดครึ่งกว่า

if(x >= 10 && x <= 19){

} else if(x >= 20 && x <= 29){

}

และต้องทำคณิตศาสตร์เพื่อรู้ว่าไม่มีค่าที่เป็นไปได้ระหว่าง 19 และ 20


ฉันเห็นแนวคิด "ความยาว" แต่จะเกิดอะไรขึ้นถ้าคุณเพียงแค่ใช้ค่าที่มาจากที่ใดที่หนึ่งและตั้งใจที่จะทำซ้ำจากค่าเริ่มต้นเป็นค่าสิ้นสุด ตัวอย่างคลาสคือมาร์กอัปเปอร์เซ็นต์จาก 5 ถึง 10 ไม่ชัดเจนที่จะพูดว่า: for (markup = 5; markup <= 10; markup ++) ... ? ทำไมฉันจะเปลี่ยนไปทดสอบ: มาร์กอัป <11 ?

6
@nocomprende คุณจะไม่ทำถ้าค่าขอบเขตจากคำอธิบายปัญหาของคุณคือ 5 และ 10 ดังนั้นจะดีกว่าถ้าให้พวกเขามีรหัสอย่างชัดเจนในโค้ดแทนที่จะเป็นค่าที่เปลี่ยนแปลงเล็กน้อย
วงล้อประหลาด

@nocomprende for(markup = 5; markup <= MAX_MARKUP; ++markup)รูปแบบที่เหมาะสมเป็นสิ่งที่เห็นได้ชัดมากขึ้นเมื่อถูกผูกไว้บนเป็นพารามิเตอร์: สิ่งอื่นใดจะทำให้เข้าใจยากเกินไป
Navin

1

ฉันจะบอกว่าประเด็นไม่ใช่ว่าคุณควรใช้> หรือ> = จุดคือการใช้สิ่งที่ช่วยให้คุณเขียนรหัสที่แสดงออก

หากคุณพบว่าคุณต้องเพิ่ม / ลบข้อใดข้อหนึ่งให้พิจารณาใช้ตัวดำเนินการอื่น ฉันพบว่าสิ่งดีๆเกิดขึ้นเมื่อคุณเริ่มต้นด้วยโมเดลที่ดีของโดเมนของคุณ จากนั้นตรรกะเขียนเอง

bool IsSpeeding(int kilometersPerHour)
{
    const int speedLimit = 90;
    return kilometersPerHour > speedLimit;
}

นี่เป็นวิธีที่แสดงออกมากกว่า

bool IsSpeeding(int kilometersPerHour)
{
    const int speedLimit = 90;
    return kilometersPerHour >= (speedLimit + 1);
}

ในกรณีอื่น ๆ วิธีอื่นเป็นที่นิยม:

bool CanAfford(decimal price, decimal balance)
{
    return balance >= price;
}

ดีกว่ามาก

bool CanAfford(decimal price, decimal balance)
{
    const decimal epsilon = 0e-10m;
    return balance > (price - epsilon);
}

โปรดแก้ตัว "ความหลงใหลดั้งเดิม" เห็นได้ชัดว่าคุณต้องการใช้ Velocity- และ Money-Type ที่นี่ตามลำดับ แต่ฉันไม่สนใจมันเลย ประเด็นคือ: ใช้รุ่นที่กระชับและช่วยให้คุณมุ่งเน้นไปที่ปัญหาทางธุรกิจที่คุณต้องการแก้ไข


2
ตัวอย่างการ จำกัด ความเร็วเป็นตัวอย่างที่ไม่ดี การไป 90kph ในโซน 90kph นั้นไม่ถือว่าเป็นการเร่งความเร็ว รวมขีด จำกัด ความเร็ว
eidsonator

คุณถูกต้องจริงๆสมองผายลมในส่วนของฉัน อย่าลังเลที่จะแก้ไขเพื่อใช้ตัวอย่างที่ดีกว่าหวังว่าจุดจะไม่หายไปอย่างสมบูรณ์
sara

0

ในขณะที่คุณชี้ให้เห็นในคำถามของคุณการทดสอบความเท่าเทียมกันในตัวแปรลอยไม่น่าเชื่อถือ

เดียวกันถือเป็นจริงสำหรับและ<=>=

อย่างไรก็ตามไม่มีปัญหาความน่าเชื่อถือดังกล่าวสำหรับประเภทจำนวนเต็ม ในความคิดของฉันผู้เขียนแสดงความคิดเห็นของเธอว่าอ่านง่ายกว่านี้

หรือไม่คุณเห็นด้วยกับเขาเป็นหลักสูตรของคุณมีความคิดเห็น


นี่เป็นมุมมองที่จัดขึ้นโดยทั่วไปโดยผู้เขียนคนอื่นและผมสีเทาในสนาม (จริง ๆ แล้วฉันมีผมหงอก)? หากเป็นเพียง "ความคิดเห็นของผู้สื่อข่าวหนึ่ง" ฉันสามารถบอกนักเรียนได้ว่า ฉันมีจริง ไม่เคยได้ยินแนวคิดนี้มาก่อน

เพศของผู้เขียนไม่เกี่ยวข้อง แต่ฉันได้ปรับปรุงคำตอบแล้ว ฉันชอบที่จะเลือก<หรือ<=ตามสิ่งที่เป็นธรรมชาติที่สุดสำหรับปัญหาเฉพาะที่ฉันกำลังแก้ไข ตามที่คนอื่น ๆ ได้ชี้ให้เห็นในการวนรอบ FOR <ทำให้สมเหตุสมผลมากขึ้นในภาษา C-type มีกรณีการใช้งานอื่น ๆ <=ที่มีประโยชน์แก่ ใช้เครื่องมือทั้งหมดในการกำจัดของคุณเมื่อใดและที่เหมาะสม
Dan Pichelman

ไม่เห็นด้วย มีสามารถเป็นปัญหาความน่าเชื่อถือกับชนิดจำนวนเต็ม: ใน C พิจารณา: for (unsigned int i = n; i >= 0; i--)หรือfor (unsigned int i = x; i <= y; i++)ถ้าจะเกิดขึ้นy UINT_MAXโอ๊ะโอวนรอบเหล่านั้นตลอดไป
jamesdlin

-1

แต่ละความสัมพันธ์<, <=, >=, >และยัง ==และ!=มีการใช้งานในกรณีของพวกเขาสำหรับการเปรียบเทียบสองค่าจุดลอยตัว แต่ละคนมีความหมายเฉพาะและควรเลือกอย่างเหมาะสม

ฉันจะให้ตัวอย่างสำหรับกรณีที่คุณต้องการตัวดำเนินการนี้อย่างแท้จริงสำหรับแต่ละกรณี (ระวังของ NaN ด้วย)

  • คุณมีฟังก์ชั่นแท้ที่มีราคาแพงfซึ่งใช้ค่าทศนิยมเป็นอินพุต เพื่อเพิ่มความเร็วในการคำนวณของคุณคุณตัดสินใจที่จะเพิ่มแคชของค่าคำนวณส่วนใหญ่เมื่อเร็ว ๆ นี้นั่นคือการทำแผนที่ตารางการค้นหาเพื่อx f(x)คุณจะต้องใช้==เพื่อเปรียบเทียบข้อโต้แย้ง
  • คุณต้องการที่จะรู้ว่าคุณสามารถหารด้วยจำนวนที่มีความหมายx? x != 0.0คุณอาจต้องการที่จะใช้
  • คุณต้องการที่จะรู้ว่าค่าxอยู่ในช่วงหน่วย? (x >= 0.0) && (x < 1.0)เป็นเงื่อนไขที่ถูกต้อง
  • คุณคำนวณดีเทอร์มีแนนต์dของเมทริกซ์และต้องการบอกว่ามันเป็นบวกแน่นอนหรือไม่? ไม่มีเหตุผลที่จะใช้สิ่งอื่นนอกจากd > 0.0นี้
  • คุณต้องการทราบว่าΣ n = 1, …, ∞ n −α diverges หรือไม่ alpha <= 1.0ฉันต้องการทดสอบ

คณิตศาสตร์จุดลอยตัว (โดยทั่วไป) ไม่แน่นอน 1.0E-10แต่นั่นไม่ได้หมายความว่าคุณควรจะกลัวมันรักษามันเป็นความมหัศจรรย์และไม่แน่นอนเสมอรักษาปริมาณสองจุดลอยตัวเท่ากับว่าพวกเขาจะอยู่ใน ทำเช่นนี้จะจริงๆทำลายคณิตศาสตร์ของคุณและก่อให้เกิดสิ่งแปลกทั้งหมดที่จะเกิดขึ้น

  • ตัวอย่างเช่นหากคุณใช้การเปรียบเทียบแบบคลุมเครือกับแคชที่กล่าวถึงข้างต้นคุณจะพบข้อผิดพลาดเฮฮา แต่ยิ่งแย่กว่านั้นฟังก์ชั่นจะไม่บริสุทธิ์อีกต่อไปและข้อผิดพลาดขึ้นอยู่กับผลลัพธ์ที่คำนวณไว้ก่อนหน้า!
  • ใช่แม้ว่าx != 0.0และyเป็นค่าจุดลอยตัวที่ จำกัดy / xไม่จำเป็นต้องมีค่า จำกัด แต่มันอาจเกี่ยวข้องกับการรู้ว่าy / xไม่ จำกัด เนื่องจากการล้นหรือเนื่องจากการดำเนินการไม่ได้กำหนดไว้อย่างดีทางคณิตศาสตร์เพื่อเริ่มต้นด้วย
  • ถ้าคุณมีฟังก์ชั่นที่มีเป็นสิ่งที่จำเป็นที่พารามิเตอร์การป้อนข้อมูลที่xมีอยู่ในช่วงเวลาที่หน่วย [0, 1) ผมจะอารมณ์เสียจริงๆถ้ามันยิงความล้มเหลวในการยืนยันเมื่อเรียกว่ามีหรือx == 0.0x == 1.0 - 1.0E-14
  • ปัจจัยที่คุณคำนวณได้อาจไม่ถูกต้อง แต่ถ้าคุณจะแกล้งว่าเมทริกซ์นั้นไม่แน่นอนแน่นอนเมื่อตัวกำหนดที่คำนวณได้คือ1.0E-30ไม่มีอะไรได้มา สิ่งที่คุณทำคือเพิ่มโอกาสในการให้คำตอบที่ผิด
  • ใช่ข้อโต้แย้งของคุณalphaอาจได้รับผลกระทบจากการปัดเศษข้อผิดพลาดดังนั้นalpha <= 1.0อาจเป็นจริงแม้ว่าค่าทางคณิตศาสตร์ที่แท้จริงสำหรับนิพจน์ที่alphaคำนวณจากอาจมีค่ามากกว่า 1 อย่างแท้จริง แต่ไม่มีอะไรที่คุณสามารถทำได้ในจุดนี้

เช่นเคยในวิศวกรรมซอฟต์แวร์จัดการข้อผิดพลาดในระดับที่เหมาะสมและจัดการเพียงครั้งเดียว หากคุณเพิ่มข้อผิดพลาดในการปัดเศษตามลำดับ1.0E-10(ดูเหมือนว่าจะเป็นค่าวิเศษที่คนส่วนใหญ่ใช้ฉันไม่รู้ว่าทำไม) ทุกครั้งที่คุณเปรียบเทียบปริมาณจุดลอยตัวคุณจะพบข้อผิดพลาดตามลำดับ1.0E+10...


1
คำตอบที่ดีที่สุด แต่เป็นที่ยอมรับเฉพาะคำถามที่แตกต่างจากคำถามที่ถาม
Dewi Morgan

-2

ชนิดของเงื่อนไขที่ใช้ในลูปอาจ จำกัด ชนิดของการปรับให้เหมาะสมที่คอมไพเลอร์สามารถทำได้ดีขึ้นหรือแย่ลง ตัวอย่างเช่นกำหนด:

uint16_t n = ...;
for (uint16_t i=1; i<=n; i++)
  ...  [loop doesn't modify i]

คอมไพเลอร์สามารถสันนิษฐานได้ว่าเงื่อนไขข้างต้นควรทำให้ลูปจบการทำงานหลังจากวนรอบ nth pass เว้นแต่ n อาจ 65535 และลูปอาจออกในบางรูปแบบอื่นที่ไม่ใช่ i เกิน n หากเงื่อนไขเหล่านั้นนำไปใช้คอมไพเลอร์จะต้องสร้างรหัสซึ่งจะทำให้เกิดการวนซ้ำเพื่อทำงานจนกว่าสิ่งอื่นที่ไม่ใช่เงื่อนไขข้างต้นทำให้มันออกจาก

ถ้าลูปถูกเขียนแทนเป็น:

uint16_t n = ...;
for (uint16_t ctr=0; ctr<n; ctr++)
{
  uint16_t i = ctr+1;
  ... [loop doesn't modify ctr]
}

คอมไพเลอร์สามารถสันนิษฐานได้อย่างปลอดภัยว่าลูปจะไม่ต้องดำเนินการมากกว่า n ครั้งและอาจทำให้สามารถสร้างโค้ดที่มีประสิทธิภาพมากขึ้น

โปรดทราบว่าการโอเวอร์โฟลว์ที่มีประเภทที่ลงชื่อสามารถมีผลกระทบที่น่ารังเกียจ ได้รับ:

int total=0;
int start,lim,mult; // Initialize values somehow...
for (int i=start; i<=lim; i++)
  total+=i*mult;

คอมไพเลอร์อาจเขียนใหม่ว่า:

int total=0;
int start,lim,mult; // Initialize values somehow...
int loop_top = lim*mult;
for (int i=start; i<=loop_top; i+=mult)
  total+=i;

การวนซ้ำดังกล่าวจะทำงานเหมือนกันกับต้นฉบับหากไม่มีการล้นในการคำนวณ แต่สามารถทำงานได้ตลอดไปแม้บนแพลตฟอร์มฮาร์ดแวร์ที่ล้นจำนวนเต็มจะมีความหมายที่สอดคล้องกัน


ใช่ฉันคิดว่ามันไกลออกไปเล็กน้อยในตำราเรียน ยังไม่ได้พิจารณา การปรับให้เหมาะสมของคอมไพเลอร์มีประโยชน์ในการทำความเข้าใจและต้องหลีกเลี่ยงการล้น แต่จริงๆแล้วมันไม่ได้เป็นแรงจูงใจสำหรับคำถามของฉัน ง่ายต่อการอ่าน x> 5 หรือ x> = 6 หรือไม่ มันขึ้นอยู่กับ ...

นอกจากว่าคุณกำลังเขียนสำหรับ Arduino ค่าสูงสุดสำหรับ int จะสูงกว่า 65535 เล็กน้อย
Corey

1
@Corey: ค่าสูงสุดสำหรับ uint16_t จะเป็น 65535 บนแพลตฟอร์มใด ๆ ที่มีประเภทอยู่ ฉันใช้ uint16_t ในตัวอย่างแรกเพราะฉันคาดหวังว่าผู้คนจำนวนมากจะรู้ค่าสูงสุดที่แน่นอนของ uint16_t มากกว่าของ uint32_t จุดเดียวกันจะใช้ในทั้งสองกรณี ตัวอย่างที่สองคือผู้ไม่เชื่อเรื่องพระเจ้าเกี่ยวกับประเภทของ "int" และแสดงถึงจุดวิกฤตพฤติกรรมที่หลายคนไม่รู้จักเกี่ยวกับคอมไพเลอร์สมัยใหม่
supercat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.