จัดรูปแบบตัวเลขทศนิยมเป็นทศนิยม


9

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

เพื่อให้แน่ใจว่าเรากำลังทำงานกับตัวเลขทศนิยมที่ถูกต้องจะต้องจัดรูปแบบที่แม่นยำเป็นข้อมูลป้อนเข้าสู่โปรแกรม รูปแบบนี้จะเป็นจำนวนเต็มสองจำนวนที่เกิดขึ้นจริงค่าจุดลอยSignificand Exponent Significand * 2 ^ Exponentโปรดทราบว่าค่าใดค่าหนึ่งอาจเป็นลบได้

ข้อมูลจำเพาะ:

  • ต้องรองรับช่วงและความแม่นยำอย่างน้อย 32 บิต (ไม่มีการป้อนข้อมูลเกินกว่านั้น)
  • ค่าที่จัดรูปแบบทศนิยมต้องเป็นรูปแบบที่แน่นอน (ใกล้มากพอที่จะรับประกันได้ว่าการปัดเศษกลับปลายที่ถูกต้องนั้นไม่ดีพอ)
  • เราไม่เชื่อถือฟังก์ชั่นการจัดรูปแบบจุดลอยตัวของไลบรารีมาตรฐานที่จะถูกต้องเพียงพอหรือเร็วพอ (เช่น:) printfดังนั้นจึงอาจไม่สามารถใช้งานได้ คุณต้องทำการฟอร์แมต อนุญาตให้ใช้ฟังก์ชั่นการจัดรูปแบบ / การแปลงแบบอินทิกรัล
  • อาจไม่มีศูนย์นำหน้าหรือต่อท้ายยกเว้นศูนย์ที่นำหน้าศูนย์ที่จำเป็น.หากไม่มีส่วนประกอบจำนวนเต็ม
  • อนุญาตให้ใช้ฟังก์ชันหรือโปรแกรมทั้งหมด

ตัวอย่าง:

1 -2 => 0.25
17 -3 => 2.125
-123 11 => -251904
17 50 => 19140298416324608
23 -13 => 0.0028076171875
3 120 => 3987683987354747618711421180841033728
3 -50 => 0.00000000000000266453525910037569701671600341796875
-3 -50 => -0.00000000000000266453525910037569701671600341796875
10 -2 => 2.5
-12345 -3 => -1543.125
0 0 => 0
161 -4 => 10.0625
512 -3 => 64

รหัสที่สั้นที่สุดชนะ


3
อนุญาตให้ใช้เลขทศนิยมความแม่นยำไม่ จำกัด หรือไม่?
Dennis

2
หากเลขชี้กำลังเป็นค่าลบเราจะลงท้ายด้วย.0หรือไม่
Sp3000

@Dennis: ใช่อนุญาตให้ใช้เลขคณิตความแม่นยำคงที่หรือไม่ จำกัด สูง
edA-qa mort-ora-y

1
ฉันคิดว่ามันไม่สอดคล้องกัน หาก0.abcไม่ใช่ศูนย์นำหน้าแสดงว่าabc.0ไม่ใช่ศูนย์ต่อท้าย
orlp

1
นอกจากนี้ยังมีการประชุมเพื่อให้ลงท้ายด้วย.0จำนวนเต็มทุกครั้งเมื่อจัดการกับจำนวนจุดลอยตัว ดูตัวอย่างหลาม: เมื่อเทียบกับstr(1.0) == '1.0' str(1) == '1'ตรรกะของคุณยังคงไม่สอดคล้องกัน
orlp

คำตอบ:


3

CJam, 43

r_'-&\ize999rim<s1e3'0e[W%999/(i_L?\+'.*sW%

ลองออนไลน์

คำอธิบาย:

โปรแกรมทำงานร่วมกับเลขชี้กำลังสูงสุดถึง 999 ใกล้เคียงกับความแม่นยำสองเท่า (64 บิต) มันแยกเครื่องหมายลบ (ถ้ามี) จากซิกนิฟิแคนด์คูณด้วย 10 999จากนั้นทำการเลื่อนบิตด้วยเลขชี้กำลังซึ่งขณะนี้เป็นการคำนวณที่แน่นอน จากนั้นเลื่อนไปทางซ้ายด้วยเลขศูนย์หากผลลัพธ์มีน้อยกว่า 1,000 หลักแยก 999 หลักสุดท้ายเป็นส่วนที่เป็นเศษส่วนลบศูนย์ต่อท้ายด้วยการแปลงกลับเป็นจำนวนเต็มเพิ่มจุดทศนิยมหากจำเป็นและทำให้ทุกอย่างกลับมารวมกัน

r_         read and duplicate the significand in string form
'-&        keep only the minus sign, if present
\          swap with the other copy of the significand
iz         convert to integer and get absolute value
e999       multiply by 10^999
ri         read the exponent and convert to integer
m<         shift left by it; negative values will shift right
            the result is an exact non-negative integer
s          convert to string
1e3'0e[    pad to the left with zero characters up to length 1000
            longer strings will be left intact
            we need 1 more than 999 for the 0.xxx case
W%         reverse the string
999/       split into slices of length 999
(          take out the first slice (reversed fractional part)
i          convert to integer
            this removes the leading zeros (trailing in reverse)
_L?        if it's zero, replace with an empty string
\+         concatenate back (to the left) with the second slice
'.*        join the with the dot character
            if the fractional part was zero, we only have the second slice
            (reversed integer part) and there is nothing to join
s          convert to string; this is the reversed result without the sign
W%         reverse back

ในตอนท้ายเครื่องหมายลบ (ถ้ามี) และสตริงสุดท้ายจะถูกพิมพ์ด้วยกันโดยอัตโนมัติ


2

CJam, 50 ไบต์

q~A1$z#\_0>K5?\z:E#@_s'-&oz*\md_sE'0e[W%isW%'.\+Q?

นี่เป็นโปรแกรมเต็มรูปแบบที่อ่านจาก STDIN ลองใช้ออนไลน์ในล่าม CJam

ตรวจสอบกรณีทดสอบทั้งหมดในครั้งเดียว


จากความคิดเห็นของคุณฉันคิดว่า CJam มีความแม่นยำไม่ จำกัด และคุณเคยใช้ที่นี่หรือไม่ ถูกต้องหรือไม่ว่าคำตอบนี้ครอบคลุมการป้อนข้อมูลใด ๆ ไม่ใช่เพียงการลอย 32 บิต? นอกจากนี้เราสามารถขอคำอธิบายว่ามันทำงานอย่างไร?
edA-qa mort-ora-y

CJam มีความแม่นยำไม่ จำกัด สำหรับจำนวนเต็ม แต่มีเพียงความแม่นยำสองเท่า ฉันคูณด้วยพลัง 20 สำหรับเลขชี้กำลังเป็นบวกและกำลัง 5 สำหรับกำลังลบ, การโยนไปยังสตริงและแทรกจุด ฉันจะเพิ่มคำอธิบายโดยละเอียดในอีกไม่กี่ชั่วโมง
Dennis

และใช่ได้รับหน่วยความจำเพียงพอซึ่งควรทำงานกับอินพุตใด ๆ
Dennis

10 -2 ดูเหมือนจะมีศูนย์ต่อท้าย
aditsu ออกเนื่องจาก SE เป็นความชั่วร้าย

@aditsu: อ่าใช่หนึ่งต่อท้ายศูนย์อำนาจของ 2 ทุก ...
เดนนิส

2

GNU sed + dc, 65

คะแนนรวม +1 สำหรับ-rตัวเลือกของ sed

y/-/_/
s/.*/dc -e"C8k& 2r^*p"/e
s/\\\n//
s/0+$//
s/^(-?)\./\10./

ฉันถูกล่อลวงให้อ้างdcคำตอบนี้เพียงC8k& 2r^*pเพื่อให้ได้คะแนน 10 แต่dcมีนิสัยใจคอการจัดรูปแบบบางอย่าง:

  • เครื่องหมาย -ve _แทน-
  • เส้นยาวหักด้วยแบ็กสแลช
  • ต้องลบศูนย์ต่อท้าย
  • ชั้นนำ 0 สำหรับ|n| < 1จะต้องเพิ่ม

ดังนั้นการแสดงออกของ dc นั้นถูกห่อหุ้มและวิวัฒนาการโดยsedการดูแลด้านบน

ผลการทดสอบ:

$ echo "1 -2
17 -3
-123 11
17 50
23 -13
3 120
3 -50
-3 -50
8388608 127
1 -127" | sed -rf float.sed
0.25
2.125
-251904
19140298416324608
0.0028076171875
3987683987354747618711421180841033728
0.00000000000000266453525910037569701671600341796875
-0.00000000000000266453525910037569701671600341796875
1427247692705959881058285969449495136382746624
0.0000000000000000000000000000000000000058774717541114375398436826861112283890933277838604376075437585313920862972736358642578125
$ 

อืมฉันคิดว่ามันdcเป็นการละเมิดกฎของฉันในการใช้ฟังก์ชั่นการจัดรูปแบบมาตรฐาน
edA-qa mort-ora-y

1
@ EDA-qamort-Ora-Y ฉันคิดว่าการใช้งานของdcก็โอเคให้"ไม่ จำกัด หรือคงสูงความแม่นยำทางคณิตศาสตร์ที่ได้รับอนุญาต" dc's pคำสั่งไม่ได้เป็น ' จุดลอยฟังก์ชั่นการจัดรูปแบบ' - มันเป็นฟังก์ชั่นการพิมพ์ที่มีความแม่นยำโดยพลการ ฉันกำลังตั้งค่าความแม่นยำเป็น 128 ตำแหน่งทศนิยม ( C8k) ซึ่งฉันคิดว่าเพียงพอสำหรับการลอยแบบ 32 บิตใด ๆ
Digital Trauma
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.