คุณสามารถเปรียบเทียบตัวเลขเพียงสองตัวกับdc
like:
dc -e "[$1]sM $2d $1<Mp"
... ที่"$1"
คุ้มค่าสูงสุดของคุณและเป็นจำนวนที่คุณพิมพ์ถ้ามันเป็นน้อยกว่า"$2"
"$1"
สิ่งนี้ต้องการ GNU ด้วยdc
เช่นกัน แต่คุณสามารถทำสิ่งเดียวกันนี้ได้เช่น:
dc <<MAX
[$1]sM $2d $1<Mp
MAX
ในทั้งสองกรณีข้างต้นคุณสามารถตั้งค่าความแม่นยำอย่างอื่นที่ไม่ใช่ 0 (เริ่มต้น)${desired_precision}k
เช่น คุณจำเป็นต้องตรวจสอบว่าทั้งสองค่านั้นเป็นตัวเลขแน่นอนเพราะdc
สามารถทำการsystem()
โทรด้วยตัว!
ดำเนินการ
ด้วยสคริปต์เล็ก ๆ น้อย ๆ ต่อไปนี้(และถัดไป)คุณควรตรวจสอบอินพุตเหมือนgrep -v \!|dc
หรือบางสิ่งบางอย่างเพื่อจัดการอินพุตโดยพลการ คุณควรรู้ด้วยว่าdc
การตีความตัวเลขลบด้วย_
คำนำหน้าแทนที่จะเป็นส่วน-
นำหน้า - เพราะตัวเลขหลังเป็นตัวดำเนินการลบ
นอกเหนือจากนั้นสคริปต์นี้dc
จะอ่าน\n
ตัวเลขที่คั่นด้วย ewline ตามจำนวนที่คุณต้องการให้และพิมพ์สำหรับแต่ละ$max
ค่าหรืออินพุตของคุณขึ้นอยู่กับว่าอะไรคือ wo:
dc -e "${max}sm
[ z 0=? d lm<M p s0 lTx ]ST
[ ? z 0!=T q ]S?
[ s0 lm ]SM lTx"
ดังนั้น ... แต่ละคน[
วงเล็บตาราง]
กว้างใหญ่เป็นdc
สตริงวัตถุที่ถูกS
aved แต่ละอาร์เรย์ของแต่ละ - หนึ่งใด ๆT
, หรือ?
M
นอกจากนี้บางสิ่งอื่น ๆdc
อาจทำกับสตริงมันยังสามารถx
หนึ่ง ecute เป็นแมโคร หากคุณจัดเรียงให้ถูกต้องdc
สคริปต์ตัวเล็กที่ทำงานได้อย่างสมบูรณ์จะถูกประกอบเข้าด้วยกันอย่างเพียงพอ
dc
ทำงานบนสแต็ก วัตถุอินพุตทั้งหมดจะซ้อนกันในช่วงสุดท้าย - แต่ละวัตถุอินพุตใหม่ผลักวัตถุชั้นนำสุดท้ายและวัตถุทั้งหมดด้านล่างลงบนสแต็กโดยหนึ่งเมื่อมีการเพิ่ม อ้างอิงส่วนใหญ่ไปยังวัตถุที่มีค่าที่สแต็คด้านบนและการอ้างอิงมากที่สุดปรากฏด้านบนของสแต็คที่(ซึ่งจะดึงวัตถุทั้งหมดที่อยู่ด้านล่างขึ้นโดยหนึ่ง)
นอกเหนือจากสแต็กหลักยังมี(อย่างน้อย) 256 อาร์เรย์และแต่ละองค์ประกอบอาเรย์จะมาพร้อมกับสแต็กทั้งหมดของตัวเอง ฉันไม่ได้ใช้สิ่งเหล่านี้ที่นี่ ฉันเพียงแค่เก็บสายดังกล่าวเพื่อให้สามารถl
OAD พวกเขาเมื่อต้องการและ e x
ecute พวกเขามีเงื่อนไขและผมs
ฉีก$max
's ค่าในด้านบนของm
อาร์เรย์
อย่างไรก็ตามสิ่งเล็กน้อยนี้dc
ทำส่วนใหญ่เชลล์สคริปต์ของคุณทำอะไร มันใช้-e
ตัวเลือกGNU-ism dc
โดยทั่วไปจะใช้พารามิเตอร์จากมาตรฐานใน - แต่คุณสามารถทำเช่นเดียวกัน:
echo "$script" | cat - /dev/tty | dc
... ถ้า$script
ดูเหมือนบิตด้านบน
มันทำงานเหมือน:
lTx
- นี่l
oads และ e x
ecutes แมโครที่เก็บไว้ในด้านบนของT
(สำหรับการทดสอบผมคิดว่า - ฉันมักจะเลือกชื่อเหล่านั้นพล)
z 0=?
- T
est จะทำการทดสอบความลึกของสแต็กที่มีz
และหากสแต็กเตอร์ว่างเปล่า(read: ถือ 0 วัตถุ)มันจะเรียก?
มาโคร
? z0!=T q
- ?
แมโครถูกตั้งชื่อสำหรับ?
dc
คำสั่ง builtin ซึ่งอ่านบรรทัดอินพุตจาก stdin แต่ฉันยังเพิ่มz
การทดสอบความลึกสแต็กอีกครั้งเพื่อให้สามารถq
ใช้โปรแกรมเล็ก ๆ น้อย ๆ ทั้งหมดถ้ามันดึงในบรรทัดว่างหรือกด EOF แต่ถ้ามัน!
ไม่สำเร็จและแทนการเติมสแต็กสำเร็จจะเรียกว่าT
est อีกครั้ง
d lm<M
- T
คือจะd
uplicate ด้านบนของสแต็คและเปรียบเทียบกับ$max
(ตามที่เก็บไว้ในm
) ถ้าm
เป็นค่าที่น้อยกว่าให้dc
เรียกM
แมโคร
s0 lm
- M
เพียงแค่โผล่ที่ด้านบนของสแต็กและทิ้งไปที่เซนต์คิตส์และเนวิส0
- เพียงวิธีที่ถูกกอง popping นอกจากนี้ยังมีการl
โหลดm
อีกครั้งก่อนกลับไปที่T
est
p
- ซึ่งหมายความว่าหากm
น้อยกว่าด้านบนสุดของสแต็กปัจจุบันจากนั้นm
แทนที่มัน( d
uplicate ของมันต่อไป)และอยู่ที่นี่p
rinted อื่นมันไม่ได้และสิ่งที่ใส่เป็นp
rinted แทน
s0
- หลังจากนั้น(เพราะp
จะไม่ปรากฏสแต็ค)เราจะทำการถ่ายโอนด้านบนของสแต็กเข้าไป0
อีกครั้งแล้ว ...
lTx
- ซ้ำl
OAD T
คืออีกครั้งแล้วอีx
ecute มันอีกครั้ง
ดังนั้นคุณสามารถเรียกใช้ตัวอย่างข้อมูลเล็ก ๆ นี้และพิมพ์ตัวเลขแบบโต้ตอบได้ที่เทอร์มินัลของคุณและdc
จะพิมพ์กลับมาที่คุณทั้งหมายเลขที่คุณป้อนหรือมูลค่า$max
ถ้าจำนวนที่คุณพิมพ์มีขนาดใหญ่ขึ้น มันจะยอมรับไฟล์ใด ๆ(เช่นไพพ์)เป็นอินพุตมาตรฐาน มันจะดำเนินการอ่าน / เปรียบเทียบ / พิมพ์ห่วงจนกว่าจะพบบรรทัดว่างหรือ EOF
หมายเหตุบางอย่างเกี่ยวกับเรื่องนี้ - ฉันเขียนสิ่งนี้เพื่อเลียนแบบพฤติกรรมในฟังก์ชันเชลล์ของคุณดังนั้นมันจึงจัดการหมายเลขหนึ่งต่อบรรทัดได้อย่างสมบูรณ์เท่านั้น dc
อย่างไรก็ตามสามารถจัดการหมายเลขที่คั่นด้วยช่องว่างต่อบรรทัดได้มากเท่าที่คุณต้องการจะโยน อย่างไรก็ตามเนื่องจากสแต็กเป็นจำนวนสุดท้ายในบรรทัดจะเป็นคนแรกที่ทำงานและดังนั้นตามที่เขียนไว้dc
จะพิมพ์เอาต์พุตในทางกลับกันถ้าคุณพิมพ์ / พิมพ์มากกว่าหนึ่งหมายเลขต่อหนึ่งบรรทัดวิธีที่เหมาะสม เพื่อจัดการนั่นคือการจัดเก็บบรรทัดในอาร์เรย์จากนั้นทำงาน
แบบนี้:
dc -e "${max}sm
[ d lm<M la 1+ d sa :a z0!=A ]SA
[ la d ;ap s0 1- d sa 0!=P ]SP
[ ? z 0=q lAx lPx l?x ]S?
[q]Sq [ s0 lm ]SM 0sa l?x"
แต่ ... ฉันไม่รู้ว่าฉันต้องการอธิบายเรื่องนี้ในเชิงลึกมากน้อยแค่ไหน เพียงพอที่จะบอกว่าเมื่อdc
อ่านค่าแต่ละค่าบนสแต็กมันจะเก็บค่าหรือค่า$max
ของมันในอาเรย์ที่จัดทำดัชนีและเมื่อตรวจพบสแต็กจะว่างเปล่าอีกครั้งจากนั้นก็พิมพ์วัตถุแต่ละดัชนี สายของอินพุต
และในขณะที่สคริปต์แรกทำ ...
10 15 20 25 30 ##my input line
20
20
20
15
10 ##see what I mean?
ที่สองทำ:
10 15 20 25 30 ##my input line
10 ##that's better
15
20
20 ##$max is 20 for both examples
20
คุณสามารถจัดการลอยของความแม่นยำโดยพลการถ้าคุณตั้งค่าด้วยk
คำสั่ง และคุณสามารถปรับเปลี่ยนi
nput หรือo
utices radices อย่างอิสระซึ่งบางครั้งอาจมีประโยชน์สำหรับเหตุผลที่คุณอาจไม่คาดคิด ตัวอย่างเช่น:
echo 100000o 10p|dc
00010
... ชุดแรกdc
ที่ส่งออก radix ถึง 100,000 แล้วพิมพ์ 10