เมื่อใดที่ฟังก์ชันตรีโกณมิติที่มีอาร์กิวเมนต์องศาให้ส่งคืน -0.0


10

ในการสร้างฟังก์ชั่นหนุนmy_sind(d), my_cosd(d), my_tand(d)ที่ใช้ในการโต้แย้งการศึกษาระดับปริญญามากกว่าเรเดียนหนึ่งและให้การตอบแน่นอนที่หลาย 90 ผมสังเกตเห็นว่าผลที่ได้บางครั้งมากกว่า-0.00.0

my_sind( 0.0) -->  0.0
my_sind(-0.0) --> -0.0

my_sind(180.0) --> -0.0
my_sind(360.0) -->  0.0

sin()และtan()โดยทั่วไปแล้วจะส่งกลับผลลัพธ์เป็นศูนย์สัญญาณเดียวกันสำหรับสัญญาณเข้าศูนย์ที่กำหนด มันสมเหตุสมผลที่my_sin()ควรตรงกับsin()อินพุตเหล่านั้น

my_sind( 0.0) alike sin( 0.0) -->  0.0
my_sind(-0.0) alike sin(-0.0) --> -0.0

คำถามคือ : สำหรับสิ่งที่จำนวนทั้งหมดnon_zero_nควร / อาจผลที่เคยกลับ-0.0สำหรับmy_sind(180*non_zero_n), my_cosd(180*n + 180), my_tand(180*non_zero_n)?

มันง่ายพอที่จะเขียนโค้ดเพื่อf(-0.0)สร้าง-0.0และทำกับมันเท่านั้น ง่าย ๆ ที่สงสัยว่ามีเหตุผลใดที่จะทำให้คนอื่น ๆ f(x)ผลตอบแทน-0.0ใด ๆ อื่น ๆ ( ไม่ใช่ศูนย์ ) xและความสำคัญของการทำประกันสัญญาณว่า


หมายเหตุ: นี่คือไม่ใช่คำถามว่าทำไม0.0เทียบกับ-0.0ที่เกิดขึ้น นี่ไม่ใช่เหตุผลcos(machine_pi/4)0.0ไม่กลับ ค่านี้เป็นคำถามของวิธีการควบคุมการสร้างของหรือ0.0 -0.0ฉันเห็นว่าดีที่สุดสำหรับคำถามการออกแบบ

คำตอบ:


4

หลักการออกแบบของ "ความประหลาดใจน้อยที่สุด" แสดงให้เห็นว่าเรามองไปที่ฟังก์ชั่นที่จัดตั้งขึ้นก่อนหน้านี้สำหรับคำแนะนำ ในกรณีนี้ฟังก์ชั่นที่สร้างไว้ใกล้เคียงที่สุดนั้นจัดทำโดยsinpiและcospiฟังก์ชั่นที่แนะนำใน IEEE Std 754-2008 (มาตรฐาน IEEE สำหรับเลขทศนิยม), ส่วนที่ 9 ฟังก์ชั่นเหล่านี้ไม่ได้เป็นส่วนหนึ่งของมาตรฐาน ISO C และ ISO C ++ ปัจจุบัน ถูกรวมเข้ากับไลบรารีคณิตศาสตร์ของแพลตฟอร์มการเขียนโปรแกรมต่างๆเช่น CUDA

ฟังก์ชั่นเหล่านี้คำนวณบาป (πx) และ cos (wherex) เมื่อการคูณด้วยπเกิดขึ้นโดยปริยายในฟังก์ชัน tanpiไม่ได้ถูกกำหนด แต่สามารถสันนิษฐานได้ว่าจะให้การทำงานตามtanpi(x) = sinpi(x) / cospi(x)แต่จะขึ้นอยู่กับเทียบเท่าทางคณิตศาสตร์ได้รับการสันนิษฐานว่าเพื่อให้การทำงานเป็นไปตาม

ตอนนี้เราสามารถกำหนดsind(x) = sinpi(x/180), cosd(x) = cospi(x/180), tand(x) = tanpi(x/180)ในลักษณะที่ใช้งานง่าย มาตรา 9.1.2 ของ IEEE-754 คาถาจากการจัดการของการขัดแย้งพิเศษสำหรับและsinpi cospiโดยเฉพาะอย่างยิ่ง:

sinPi (+ n) คือ +0 และ sinPi (−n) คือ −0 สำหรับจำนวนเต็มบวก n นี่หมายถึงภายใต้โหมดการปัดเศษที่เหมาะสม sinPi (−x) และ −sinPi (x) เป็นหมายเลขเดียวกัน (หรือทั้งสอง NaN) สำหรับ x ทั้งหมด cosPi (n + ½) คือ +0 สำหรับจำนวนเต็มใด ๆ n เมื่อ n + ½สามารถแทนได้

มาตรฐาน IEEE 754-2008 ไม่ได้ให้เหตุผลสำหรับข้อกำหนดที่ยกมาอย่างไรก็ตามร่างแรกของรัฐส่วนที่เกี่ยวข้อง:

หากค่าของฟังก์ชันเป็นศูนย์สัญญาณของ 0 นี้จะถูกกำหนดที่ดีที่สุดโดยพิจารณาการขยายอย่างต่อเนื่องของฟังก์ชั่นสัญญาณของฟังก์ชั่นทางคณิตศาสตร์

เมื่อพิจารณาจากที่เก็บจดหมายของกลุ่มทำงาน 754อาจให้ข้อมูลเชิงลึกเพิ่มเติมฉันไม่ได้มีเวลาขุดผ่าน การดำเนินการsind(), cosd()และtand()ตามที่อธิบายไว้ข้างต้นแล้วเราก็มาถึงที่โต๊ะของกรณีตัวอย่างนี้

SIND
 angle value 
  -540 -0
  -360 -0
  -180 -0
     0  0
   180  0
   360  0
   540  0

COSD
 angle value
  -630  0
  -450  0
  -270  0
   -90  0
    90  0
   270  0
   450  0

TAND
 angle value
  -540  0
  -360 -0
  -180  0
     0  0
   180 -0
   360  0
   540 -0

5

sin () และ tan () โดยทั่วไปแล้วจะส่งคืนผลลัพธ์เป็นศูนย์สัญญาณเดียวกันสำหรับสัญญาณอินพุตที่กำหนดเป็นศูนย์

มันอาจเป็นจริงโดยทั่วไปตั้งแต่:

  • ความเร็ว / ความถูกต้อง สำหรับคู่ขนาดเล็กพอคำตอบที่ดีที่สุดสำหรับการเป็นsin(x) xนั่นคือสำหรับตัวเลขที่เล็กกว่าประมาณ1.49e-8คู่ที่ใกล้เคียงกับไซน์ของ x คือตัว x จริง ๆ (ดูรหัสแหล่ง glibc สำหรับ sin () )

  • การจัดการกรณีพิเศษ

    การดำเนินการทางคณิตศาสตร์ที่ไม่ธรรมดาจำนวนเล็กน้อยได้รับผลกระทบจากเครื่องหมายของศูนย์ ตัวอย่างเช่นแต่"1/(+0) = +inf" "1/(-0) = -inf"เพื่อรักษาประโยชน์ของบิตบิตจะต้องเผยแพร่ผ่านการดำเนินการทางคณิตศาสตร์บางอย่างตามกฎที่ได้มาจากการพิจารณาต่อเนื่อง

    การใช้งานฟังก์ชั่นชั้นเยี่ยมระดับประถมศึกษาเช่น sin (z) และ tan (z) และผู้รุกรานและอนาล็อกแบบไฮเปอร์โบลิกแม้ว่าจะไม่ได้ระบุไว้ในมาตรฐาน IEEE คาดว่าจะปฏิบัติตามกฎที่คล้ายคลึงกัน การดำเนินการsin(z) คาดว่าจะทำซ้ำสัญลักษณ์ของzz = ±Oเช่นเดียวกับความคุ้มค่าที่

    ( สาขาตัดสำหรับฟังก์ชั่นระดับประถมศึกษาที่ซับซ้อนหรือความกังวลใจมากเกี่ยวกับบิตเครื่องหมายไม่มีอะไรโดย W. Kahan)

    การลงนามในเชิงลบศูนย์สะท้อนแนวคิดการวิเคราะห์ทางคณิตศาสตร์ของการเข้าใกล้ 0 จากด้านล่างเป็นขีด จำกัด ด้านเดียว (พิจารณา1 / sin(x): เครื่องหมายของศูนย์ทำให้แตกต่างกันมาก)

แก้ไข

เมื่อพิจารณาถึงประเด็นที่สองฉันจะเขียนmy_sindว่า:

my_sind(-0.0) is -0.0
my_sind(0.0) is 0.0

มาตรฐาน C ล่าสุด (F.10.1.6 sinและ F.10.1.7 tanการใช้งานที่มีการลงนามในศูนย์) ระบุว่าถ้าอาร์กิวเมนต์เป็น±0, มันจะถูกส่งกลับแปรมันจะถูกส่งกลับแปร

แก้ไข 2

สำหรับค่าอื่น ๆ ฉันคิดว่ามันเป็นเรื่องของการประมาณ รับM_PI<π:

0 = sin(π) < sin(M_PI)  1.2246467991473532e-16  +0.0
0 = sin(-π) > sin(-M_PI)  -1.2246467991473532e-16  -0.0
0 = sin(2*π) > sin(2*M_PI)  -2.4492935982947064e-16
0 = sin(-2*π) < sin(-2*M_PI)  2.4492935982947064e-16

ดังนั้นหากmy_sindให้คำตอบที่แน่นอนที่ทวีคูณ 180 °ก็สามารถกลับมาได้+0.0หรือ-0.0(ฉันไม่เห็นเหตุผลชัดเจนที่จะชอบอีกข้อหนึ่ง)

หากmy_sindใช้การประมาณบางอย่าง (เช่นdegree * M_PI / 180.0สูตรการแปลง) ควรพิจารณาว่าใกล้ถึงค่าวิกฤตอย่างไร


คุณคิดsind(180), sind(-180), sind(360), sind(-360),...อย่างไรเกี่ยวกับ
chux - Reinstate Monica

ขอบคุณสำหรับการอัพเดท. บางทีโพสต์ของฉันอาจไม่ชัดเจน คำถามหลักคือควรmy_trig(x)กลับ-0.0เมื่อ|x|ไม่0.0?
chux - Reinstate Monica

ขอบคุณสำหรับ "ดังนั้นหาก my_sind ให้คำตอบที่แน่นอนที่ทวีคูณของ 180 °ก็สามารถส่งกลับ +0.0 หรือ -0.0 (ฉันไม่เห็นเหตุผลที่ชัดเจนที่จะชอบมากกว่าหนึ่งอื่น ๆ )" มันเป็นจุดสนทนาที่ใกล้ที่สุด ฉันคิดว่า "หลักการของความประหลาดใจอย่างน้อยที่สุด" กระตุ้นให้กลับมาเสมอ+0.0แต่มองหาว่ามีเหตุผลที่น่าสนใจที่จะกลับมา-0.0ในบางสถานการณ์ (นอกเหนือจากx == +/-0.0)
chux - Reinstate Monica

@ chux: ฉันคิดว่าหลายรายการ180.0จริงๆต้องตรวจสอบค่าของความแม่นยำเครื่องญาติให้ค่าเหล่านั้น นั่นคือการเพิ่ม / ลดที่เล็กที่สุดซึ่งให้ค่าที่สามารถแทนได้แตกต่างกันในรูปแบบตัวเลขนั้น จากนั้นเปรียบเทียบค่านั้นกับมูลค่าที่แท้จริงเพื่อดูว่ามันจะตกอยู่ที่ด้านบวกหรือด้านลบ

@rwong ขอบคุณสำหรับความคิด ชุดละ 90.0 องศาที่แน่นอน sind(double degrees)และคุ้มค่าสามารถนำกลับมาว่า:cosd(double degrees) -1.0, +0.0, +1.0โพสต์นี้เป็นเรื่องเกี่ยวกับที่ควร-0.0จะกลับ (นอกเหนือจาก sind (-0.0)) หมายเหตุ: sind()ไม่ได้ใช้sin(x/360*M_PI)วิธีการที่ง่าย
chux - Reinstate Monica

3

ไลบรารีไม่พยายามแยกความแตกต่าง +0 จาก -0 IEEE 754 กังวลเล็กน้อยเกี่ยวกับความแตกต่างนี้ ... ฉันพบว่าฟังก์ชั่น [ในวิชาคณิตศาสตร์] นั้นค่อนข้างยากพอที่จะเขียนโดยไม่ต้องกังวลเกี่ยวกับสัญลักษณ์ของอะไรเลย - PJ Plauger, ห้องสมุด Standard C , 1992, หน้า 128

ฟังก์ชั่นตรีโกณมิติควรกลับเครื่องหมายศูนย์ตามมาตรฐาน C ... ซึ่งทำให้พฤติกรรมไม่ได้กำหนด

ในหน้าของพฤติกรรมที่ไม่ได้กำหนดไว้ในหลักการของความประหลาดใจอย่างน้อยmath.hแสดงให้เห็นการทำซ้ำลักษณะการทำงานของฟังก์ชั่นที่สอดคล้องกันจาก สิ่งนี้มีกลิ่นที่สมเหตุสมผลในขณะที่แยกออกจากพฤติกรรมของฟังก์ชั่นที่เกี่ยวข้องในmath.hกลิ่นเหมือนวิธีที่จะแนะนำข้อบกพร่องเข้าไปในรหัสซึ่งขึ้นอยู่กับเครื่องหมายของศูนย์


ฟังก์ชันตรีโกณฯ ในmath.hไม่ส่งคืน 0.0 เมื่ออาร์กิวเมนต์ที่กำหนดเช่น +/- pi / 2 หรือ +/- pi เนื่องจากฟังก์ชันเหล่านี้สามารถรับค่าที่สามารถแทนได้ใกล้ +/- pi / 2 เป็นต้น ค่า "ใกล้" เหล่านี้ส่งคืนผลลัพธ์ใกล้ 0.0 เนื่องจากฟังก์ชันsin cos tanตรีโกณมิติไลบรารี std ( ) ไม่ส่งคืน 0.0 (หรือ -0.0) สำหรับอินพุตใด ๆ (ยกเว้น +/- 0.0) แต่ my_sind (), my_cosd (), my_tand () สามารถส่งคืน 0.0 (หรือ -0.0) ที่นั่น ไม่มี 0.0 พฤติกรรมการทำซ้ำ
chux - Reinstate Monica

@chux หลักฐานที่sin(-0.0)ควรกลับ-0เป็นผู้ต้องสงสัย มันปฏิบัติต่อรายละเอียดการดำเนินงานของมาตรฐาน IEEE เป็นหลักการตรีโกณมิติ แม้ว่าจะมีหลักการทางคณิตศาสตร์ทั่วไปที่ศูนย์เป็นขีด จำกัด ของสองช่วงเวลาที่เป็นตัวเป็นตนในการใช้งาน IEEE มันเกิดขึ้นในระดับที่เป็นนามธรรมที่ไม่ได้อยู่ในระดับตรีโกณมิติทั่วไป [ดังนั้นความแปรปรวนในฟังก์ชันตรีโกณมิติของคุณกลับมา] สิ่งที่ดีที่สุดที่สามารถเกิดขึ้นได้คือคุณสามารถกำหนดอนุสัญญาโดยพลการ แต่มันจะแตกต่างจากความไร้math.hสาระของสัญญาณศูนย์
Ben rudgers

หมายเหตุ: ผมไม่ได้บอกsin(-0.0)ควรจะกลับ-0.0แต่ที่my_sind(x)ควรจะตรงกับsin(x)เมื่อเป็นx +/-0.0IOW: ติดตามการปฏิบัติก่อนหน้า คำถามเพิ่มเติมนั้นเกี่ยวกับสิ่งที่ต้องทำเมื่อx != 0.0ควรmy_sind(x)กลับมา-0.0เหมือนในmy_sind(180)หรือไม่? อาจเป็นคำตอบ / ความเห็นของคุณที่ - แต่ฉันไม่เห็น
chux - Reinstate Monica

@chux หากพฤติกรรมไม่ได้กำหนดไว้แสดงว่าไม่ได้กำหนด นั่นเป็นวิธีที่ C เป็น ผู้วางเครื่องไม่ต้องกังวล+0กับ-0เมื่อเขาเขียนmath.hเมื่อยี่สิบปีก่อน ยังไม่ชัดเจนสำหรับฉันว่าปัญหาที่คุณกังวลเกี่ยวกับความแตกต่างกำลังแก้ไขอยู่
Ben rudgers

1
หวังว่าคุณจะเห็นว่าสำหรับการดำเนินการอย่างดีsin(rad)สำหรับค่าใด ๆrad>0และความแม่นยำใด ๆ จะไม่ยอมให้ผลลัพธ์0.0เพราะ pi ไม่มีเหตุผล [Ref] (www.csee.umbc.edu/~phatak/645/supl/Ng-ArgReduction.pdf) อย่างไรก็ตามmy_sind(deg)ผลตอบแทนที่แน่นอน0.0(อย่างใดอย่างหนึ่ง + หรือ -) ทุกตัวคูณของ180.0ค่า 0.0 เป็นผลลัพธ์ทางคณิตศาสตร์ที่ถูกต้อง "หลักการของความประหลาดใจน้อยที่สุด" แนะนำการกลับมา 0.0 ในกรณีเหล่านี้ คำถามของฉันควร-0.0ส่งคืนในกรณีเหล่านี้หรือไม่
chux - Reinstate Monica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.