2016-12-29 17 views
8

Tôi đang làm việc với các vĩ độ và kinh độ để xác định vị trí doanh nghiệp và gặp phải một số hành vi kỳ lạ.Tại sao tôi nhận được kết quả khác khi tôi thực hiện phép toán trên biến được trích dẫn và không được trích dẫn?

Trong đoạn mã Perl bên dưới, phương trình gán dữ liệu cho $v1 đánh giá thành 1. Khi tôi gọi acos($v1), tôi nhận được lỗi sqrt. Khi tôi gọi acos("$v1") (có dấu ngoặc kép), tôi thì không. Gọi số acos(1) cũng không gây ra lỗi. Tại sao các dấu ngoặc kép lại quan trọng?

use strict; 
use warnings 'all'; 

sub acos { 
    my $rad = shift; 
    return (atan2(sqrt(1 - $rad**2), $rad)); 
} 

my $v1 = (0.520371764072297 * 0.520371764072297) + 
     (0.853939826425894 * 0.853939826425894 * 1); 

print acos($v1); # Can't take sqrt of -8.88178e-16 at foo line 8. 
print acos("$v1"); # 0 
+0

liên quan: [Bug # 127.182 cho Perl5: Một chữ số ngắn để stringify một cách chính xác một đôi] (https://rt.perl.org/Public/Bug/Display.html?id=127182) – ThisSuitIsBlackNot

+0

Xem thêm [Tại sao Perl không phù hợp với làm tròn sprintf?] (http://stackoverflow.com/q/ 41312890/2173773) –

Trả lời

15

$v1 là không chính xác 1:

$ perl -e' 
    $v1 = (0.520371764072297 * 0.520371764072297) + 
      (0.853939826425894 * 0.853939826425894 * 1); 
    printf "%.16f\n", $v1 
' 
1.0000000000000004 

Tuy nhiên, khi bạn stringify nó, Perl only keeps 15 digits of precision:

$ perl -MDevel::Peek -e' 
    $v1 = (0.520371764072297 * 0.520371764072297) + 
      (0.853939826425894 * 0.853939826425894 * 1); 
    Dump "$v1" 
' 
SV = PV(0x2345090) at 0x235a738 
    REFCNT = 1 
    FLAGS = (PADTMP,POK,pPOK) 
    PV = 0x2353980 "1"\0  # string value is exactly 1 
    CUR = 1 
    LEN = 16 
+0

dữ liệu tốt. cảm ơn. – x2m

+0

Tài nguyên hay, cảm ơn bạn. Tôi đã tìm kiếm và không thể định vị nó trong tài liệu. – zdim

+0

Cảm ơn bạn đã bình luận của bạn [ở đây] (http://stackoverflow.com/questions/41400902/why-does-foo-bar-autovivify-but-foo-doesnt). Đây là tiền thưởng của bạn như tôi hứa ;-) –

Các vấn đề liên quan