ให้ x = 10,y = 5 และ z = x*y+--y จะได้ z = 54 แต่ถ้าเขียนใหม่ เป็น z = --y+x*y จะได้ z = 44 คำถามคือ ทั้งๆที่ pre-decrement มี precedence สูงกว่า คูณ หาร แต่ทำไมอันแรกถึงไม่ทำ --y ก่อนแต่อันล่างกลับทำก่อน?
เขาหมายถึงจะทำก่อนมาบวกกัน nat3738 Thu, 17/12/2009 - 22:20 เขาหมายถึงจะทำก่อนมาบวกกัน คือ อันแรก xy*(--y)+ (เป็น post-order) คือ เอา x*y แล้ว ยัดเข้า stack จากนั้นเจอ --y จึงลดค่า y ลงหนึ่ง แล้วนำค่า y ที่ลดแล้วมาใช้ในการบวก ซึ่งทำทีหลังการลดค่า ถ้าผมเข้าใจไม่ผิดนะครับ Log in or register to post comments +*xy--y +--y*xy soginal Thu, 17/12/2009 - 23:07 +*xy--y +--y*xy Log in or register to post comments ไม่นิยามไว้ครับ luckyman Thu, 17/12/2009 - 23:49 ไม่นิยามไว้ครับ ขึ้นอยู่กับคอมไพเลอร์ (ISO C99 หัวข้อ 6.5 Expression ดู footnote 73-74) จากผลลัพธ์ข้างบน คอมไพเลอร์ทำจากซ้ายไปขวาครับ ตัวแรก 1) _ <- x * y 2) y <- y - 1 3) z <- y + _ ตัวหลัง 1) y <- y - 1 2) _ <- x * y 3) z <- y + _ ผลลัพธ์จาก gcc 4.4 ได้ตามด้านบนครับ ส่วน visual c++ 2008 ได้ผลลัพธ์เป็น 44 ทั้งคู่ Log in or register to post comments ขอบคุณทุกท่านมากครับ ขอถามเพิ Peace Fri, 18/12/2009 - 00:59 ขอบคุณทุกท่านมากครับ ขอถามเพิ่มเติมว่า ถ้า compiler(gcc) ทำจากซ้ายไปขาย แล้วทำไม z = x*y+x*--y จึงได้ z = 80 หรอครับ คือ ถ้าทำจากซ้่ายมาขวา ผมเข้าใจว่า มันจะทำ x*y ก่อน ตามด้วย x*--y แล้วค่อยบวกกัน ซึ่งน่าจะได้ 50+40=90 แต่ไม่ใช่ Log in or register to post comments จริงด้วย ดูจากไฟล์ assembly luckyman Fri, 18/12/2009 - 01:53 In reply to ขอบคุณทุกท่านมากครับ ขอถามเพิ by Peace จริงด้วย ดูจากไฟล์ assembly กลายเป็น --y; y += y; z = x * y; movl $10, 24(%esp) movl $5, 28(%esp) decl 28(%esp) movl 28(%esp), %eax addl %eax, %eax imull 24(%esp), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf แถมถ้าคอมไพล์ด้วย -O2 movl $80, 4(%esp) movl $LC0, (%esp) call _printf สรุปคือ ไม่เข้าใจเหมือนกัน Log in or register to post comments อย่าไปดู assembly ครับ soginal Fri, 18/12/2009 - 09:54 In reply to จริงด้วย ดูจากไฟล์ assembly by luckyman อย่าไปดู assembly ครับ เดี๋ยวงงเปล่าๆ จริงๆ ถ้าจขกท กำลังเรียนเรื่องวิชา compiler ก็ดูตามหลักการ prefix postfix ก็น่าจะพอแล้ว ส่วนในกรณีนี้เกิดจากความพยายามทำ optimize ของ compiler ครับ x*y+x*--y เปลี่ยนได้เป็น x*(y+--y) หรือ (y+--y)*x ครับ แต่มันเอา y+--y มาทำก่อน ก็เพราะว่า มันมี --y อยู่ ก็เลยดึงมาทำก่อนครับ แต่ที่มันเอา y+--y มาทำก่อนเพราะเหตุผลว่า จะเอา z ไปคูณไม่ได้จนกว่าจะทำ y+y ก่อน แต่จะทำ y+y ไม่ได้จนกว่าจะทำ --y ดังนั้นผลลัพธ์มันก็เลยออกมาอย่างที่เห็น Log in or register to post comments ขอแนะนำนะครับ ใส่วงเล็บให้เป็ Thaina Fri, 18/12/2009 - 15:58 ขอแนะนำนะครับ ใส่วงเล็บให้เป็นนิสัยครับ สูตรคำนวน ต้องการอะไร ใส่ให้ชัดเจนไว้ มาอ่านวันหลังจะได้รู้เรื่อง เขียนไว้โล่งๆแบบนี้ บางทีหนึ่งชี่วโมงผ่านไป อาจจะลืมไปแล้วว่าสูตรนี้จะ Flow แบบไหน a * b - c ผมยังใส่ (a * b) - c เลย แล้วอย่าเล่นกับ --x --y ดีกว่าครับ Performance ที่ได้ ไม่น่าจะคุ้มกับความงงที่จะเกิดขึ้น มันไปตีกับ Compiler อีกตะหาก Log in or register to post comments จริงครับ สำหรับการ coding PiKO Fri, 18/12/2009 - 21:59 In reply to ขอแนะนำนะครับ ใส่วงเล็บให้เป็ by Thaina จริงครับ สำหรับการ coding จริงๆ ทั้งวงเล็บและขึ้นบรรทัดใหม่ ถ้าทำได้โดยที่ทำให้ code ไม่รกและดูยาก ผมก็จะทำเสมอ แต่นี่เข้าใจว่าต้องการศึกษาน่ะครับ (ไม่รู้จะอธิบายยังไงเหมือนกัน ^^') Log in or register to post comments มันเป็นเรื่องของการศึกษาน่ะคร mr_tawan Tue, 22/12/2009 - 22:24 In reply to ขอแนะนำนะครับ ใส่วงเล็บให้เป็ by Thaina มันเป็นเรื่องของการศึกษาน่ะครับ :-) Log in or register to post comments จะสอบแล้วอ่ะดิคับ 555 ellipsis Fri, 18/12/2009 - 17:11 จะสอบแล้วอ่ะดิคับ 555 Log in or register to post comments ขอบคุณทุกท่านมากครับ สรุปคือ Peace Fri, 18/12/2009 - 19:19 ขอบคุณทุกท่านมากครับ สรุปคือ มันขึ้นอยู่กับ compiler ว่าจะมองยังไง Log in or register to post comments
เขาหมายถึงจะทำก่อนมาบวกกัน nat3738 Thu, 17/12/2009 - 22:20 เขาหมายถึงจะทำก่อนมาบวกกัน คือ อันแรก xy*(--y)+ (เป็น post-order) คือ เอา x*y แล้ว ยัดเข้า stack จากนั้นเจอ --y จึงลดค่า y ลงหนึ่ง แล้วนำค่า y ที่ลดแล้วมาใช้ในการบวก ซึ่งทำทีหลังการลดค่า ถ้าผมเข้าใจไม่ผิดนะครับ Log in or register to post comments
ไม่นิยามไว้ครับ luckyman Thu, 17/12/2009 - 23:49 ไม่นิยามไว้ครับ ขึ้นอยู่กับคอมไพเลอร์ (ISO C99 หัวข้อ 6.5 Expression ดู footnote 73-74) จากผลลัพธ์ข้างบน คอมไพเลอร์ทำจากซ้ายไปขวาครับ ตัวแรก 1) _ <- x * y 2) y <- y - 1 3) z <- y + _ ตัวหลัง 1) y <- y - 1 2) _ <- x * y 3) z <- y + _ ผลลัพธ์จาก gcc 4.4 ได้ตามด้านบนครับ ส่วน visual c++ 2008 ได้ผลลัพธ์เป็น 44 ทั้งคู่ Log in or register to post comments
ขอบคุณทุกท่านมากครับ ขอถามเพิ Peace Fri, 18/12/2009 - 00:59 ขอบคุณทุกท่านมากครับ ขอถามเพิ่มเติมว่า ถ้า compiler(gcc) ทำจากซ้ายไปขาย แล้วทำไม z = x*y+x*--y จึงได้ z = 80 หรอครับ คือ ถ้าทำจากซ้่ายมาขวา ผมเข้าใจว่า มันจะทำ x*y ก่อน ตามด้วย x*--y แล้วค่อยบวกกัน ซึ่งน่าจะได้ 50+40=90 แต่ไม่ใช่ Log in or register to post comments
จริงด้วย ดูจากไฟล์ assembly luckyman Fri, 18/12/2009 - 01:53 In reply to ขอบคุณทุกท่านมากครับ ขอถามเพิ by Peace จริงด้วย ดูจากไฟล์ assembly กลายเป็น --y; y += y; z = x * y; movl $10, 24(%esp) movl $5, 28(%esp) decl 28(%esp) movl 28(%esp), %eax addl %eax, %eax imull 24(%esp), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf แถมถ้าคอมไพล์ด้วย -O2 movl $80, 4(%esp) movl $LC0, (%esp) call _printf สรุปคือ ไม่เข้าใจเหมือนกัน Log in or register to post comments
อย่าไปดู assembly ครับ soginal Fri, 18/12/2009 - 09:54 In reply to จริงด้วย ดูจากไฟล์ assembly by luckyman อย่าไปดู assembly ครับ เดี๋ยวงงเปล่าๆ จริงๆ ถ้าจขกท กำลังเรียนเรื่องวิชา compiler ก็ดูตามหลักการ prefix postfix ก็น่าจะพอแล้ว ส่วนในกรณีนี้เกิดจากความพยายามทำ optimize ของ compiler ครับ x*y+x*--y เปลี่ยนได้เป็น x*(y+--y) หรือ (y+--y)*x ครับ แต่มันเอา y+--y มาทำก่อน ก็เพราะว่า มันมี --y อยู่ ก็เลยดึงมาทำก่อนครับ แต่ที่มันเอา y+--y มาทำก่อนเพราะเหตุผลว่า จะเอา z ไปคูณไม่ได้จนกว่าจะทำ y+y ก่อน แต่จะทำ y+y ไม่ได้จนกว่าจะทำ --y ดังนั้นผลลัพธ์มันก็เลยออกมาอย่างที่เห็น Log in or register to post comments
ขอแนะนำนะครับ ใส่วงเล็บให้เป็ Thaina Fri, 18/12/2009 - 15:58 ขอแนะนำนะครับ ใส่วงเล็บให้เป็นนิสัยครับ สูตรคำนวน ต้องการอะไร ใส่ให้ชัดเจนไว้ มาอ่านวันหลังจะได้รู้เรื่อง เขียนไว้โล่งๆแบบนี้ บางทีหนึ่งชี่วโมงผ่านไป อาจจะลืมไปแล้วว่าสูตรนี้จะ Flow แบบไหน a * b - c ผมยังใส่ (a * b) - c เลย แล้วอย่าเล่นกับ --x --y ดีกว่าครับ Performance ที่ได้ ไม่น่าจะคุ้มกับความงงที่จะเกิดขึ้น มันไปตีกับ Compiler อีกตะหาก Log in or register to post comments
จริงครับ สำหรับการ coding PiKO Fri, 18/12/2009 - 21:59 In reply to ขอแนะนำนะครับ ใส่วงเล็บให้เป็ by Thaina จริงครับ สำหรับการ coding จริงๆ ทั้งวงเล็บและขึ้นบรรทัดใหม่ ถ้าทำได้โดยที่ทำให้ code ไม่รกและดูยาก ผมก็จะทำเสมอ แต่นี่เข้าใจว่าต้องการศึกษาน่ะครับ (ไม่รู้จะอธิบายยังไงเหมือนกัน ^^') Log in or register to post comments
มันเป็นเรื่องของการศึกษาน่ะคร mr_tawan Tue, 22/12/2009 - 22:24 In reply to ขอแนะนำนะครับ ใส่วงเล็บให้เป็ by Thaina มันเป็นเรื่องของการศึกษาน่ะครับ :-) Log in or register to post comments
จะสอบแล้วอ่ะดิคับ 555 ellipsis Fri, 18/12/2009 - 17:11 จะสอบแล้วอ่ะดิคับ 555 Log in or register to post comments
ขอบคุณทุกท่านมากครับ สรุปคือ Peace Fri, 18/12/2009 - 19:19 ขอบคุณทุกท่านมากครับ สรุปคือ มันขึ้นอยู่กับ compiler ว่าจะมองยังไง Log in or register to post comments
เขาหมายถึงจะทำก่อนมาบวกกัน
nat3738 Thu, 17/12/2009 - 22:20
เขาหมายถึงจะทำก่อนมาบวกกัน คือ
อันแรก
xy*(--y)+ (เป็น post-order)
คือ เอา x*y แล้ว ยัดเข้า stack
จากนั้นเจอ --y จึงลดค่า y ลงหนึ่ง แล้วนำค่า y ที่ลดแล้วมาใช้ในการบวก ซึ่งทำทีหลังการลดค่า
ถ้าผมเข้าใจไม่ผิดนะครับ
+*xy--y +--y*xy
soginal Thu, 17/12/2009 - 23:07
+*xy--y +--y*xy
ไม่นิยามไว้ครับ
luckyman Thu, 17/12/2009 - 23:49
ไม่นิยามไว้ครับ ขึ้นอยู่กับคอมไพเลอร์ (ISO C99 หัวข้อ 6.5 Expression ดู footnote 73-74)
จากผลลัพธ์ข้างบน คอมไพเลอร์ทำจากซ้ายไปขวาครับ
ตัวแรก
1) _ <- x * y 2) y <- y - 1 3) z <- y + _ตัวหลัง
1) y <- y - 1 2) _ <- x * y 3) z <- y + _ผลลัพธ์จาก gcc 4.4 ได้ตามด้านบนครับ
ส่วน visual c++ 2008 ได้ผลลัพธ์เป็น 44 ทั้งคู่
ขอบคุณทุกท่านมากครับ ขอถามเพิ
Peace Fri, 18/12/2009 - 00:59
ขอบคุณทุกท่านมากครับ
ขอถามเพิ่มเติมว่า ถ้า compiler(gcc) ทำจากซ้ายไปขาย แล้วทำไม z = x*y+x*--y จึงได้ z = 80 หรอครับ คือ ถ้าทำจากซ้่ายมาขวา ผมเข้าใจว่า มันจะทำ x*y ก่อน ตามด้วย x*--y แล้วค่อยบวกกัน ซึ่งน่าจะได้ 50+40=90 แต่ไม่ใช่
จริงด้วย ดูจากไฟล์ assembly
luckyman Fri, 18/12/2009 - 01:53
In reply to ขอบคุณทุกท่านมากครับ ขอถามเพิ by Peace
จริงด้วย ดูจากไฟล์ assembly กลายเป็น
--y; y += y; z = x * y;แถมถ้าคอมไพล์ด้วย -O2
สรุปคือ ไม่เข้าใจเหมือนกัน
อย่าไปดู assembly ครับ
soginal Fri, 18/12/2009 - 09:54
In reply to จริงด้วย ดูจากไฟล์ assembly by luckyman
อย่าไปดู assembly ครับ เดี๋ยวงงเปล่าๆ จริงๆ ถ้าจขกท กำลังเรียนเรื่องวิชา compiler ก็ดูตามหลักการ prefix postfix ก็น่าจะพอแล้ว
ส่วนในกรณีนี้เกิดจากความพยายามทำ optimize ของ compiler ครับ
x*y+x*--y เปลี่ยนได้เป็น x*(y+--y) หรือ (y+--y)*x ครับ
แต่มันเอา y+--y มาทำก่อน ก็เพราะว่า มันมี --y อยู่ ก็เลยดึงมาทำก่อนครับแต่ที่มันเอา y+--y มาทำก่อนเพราะเหตุผลว่า จะเอา z ไปคูณไม่ได้จนกว่าจะทำ y+y ก่อน แต่จะทำ y+y ไม่ได้จนกว่าจะทำ --y ดังนั้นผลลัพธ์มันก็เลยออกมาอย่างที่เห็น
ขอแนะนำนะครับ ใส่วงเล็บให้เป็
Thaina Fri, 18/12/2009 - 15:58
ขอแนะนำนะครับ
ใส่วงเล็บให้เป็นนิสัยครับ สูตรคำนวน ต้องการอะไร ใส่ให้ชัดเจนไว้
มาอ่านวันหลังจะได้รู้เรื่อง
เขียนไว้โล่งๆแบบนี้ บางทีหนึ่งชี่วโมงผ่านไป อาจจะลืมไปแล้วว่าสูตรนี้จะ Flow แบบไหน
a * b - c ผมยังใส่ (a * b) - c เลย
แล้วอย่าเล่นกับ --x --y ดีกว่าครับ
Performance ที่ได้ ไม่น่าจะคุ้มกับความงงที่จะเกิดขึ้น
มันไปตีกับ Compiler อีกตะหาก
จริงครับ สำหรับการ coding
PiKO Fri, 18/12/2009 - 21:59
In reply to ขอแนะนำนะครับ ใส่วงเล็บให้เป็ by Thaina
จริงครับ สำหรับการ coding จริงๆ ทั้งวงเล็บและขึ้นบรรทัดใหม่
ถ้าทำได้โดยที่ทำให้ code ไม่รกและดูยาก ผมก็จะทำเสมอ
แต่นี่เข้าใจว่าต้องการศึกษาน่ะครับ (ไม่รู้จะอธิบายยังไงเหมือนกัน ^^')
มันเป็นเรื่องของการศึกษาน่ะคร
mr_tawan Tue, 22/12/2009 - 22:24
In reply to ขอแนะนำนะครับ ใส่วงเล็บให้เป็ by Thaina
มันเป็นเรื่องของการศึกษาน่ะครับ :-)
จะสอบแล้วอ่ะดิคับ 555
ellipsis Fri, 18/12/2009 - 17:11
จะสอบแล้วอ่ะดิคับ
555
ขอบคุณทุกท่านมากครับ สรุปคือ
Peace Fri, 18/12/2009 - 19:19
ขอบคุณทุกท่านมากครับ สรุปคือ มันขึ้นอยู่กับ compiler ว่าจะมองยังไง