2012-01-28 36 views
6

Tôi đang cố gắng để printf một __float128 sử dụng libquadmath, ví dụ:Độ chính xác printf bắt buộc cho __float128 để không làm mất thông tin là gì?

quadmath_snprintf(s, sizeof(s), "%.30Qg", f); 

Với ba constaints sau:

  1. Sản lượng phải phù hợp với sản xuất sau:

    number = [ minus ] int [ frac ] [ exp ] 
    
    decimal-point = %x2E  ; . 
    
    digit1-9 = %x31-39   ; 1-9 
    
    e = %x65/%x45   ; e E 
    
    exp = e [ minus/plus ] 1*DIGIT 
    
    frac = decimal-point 1*DIGIT 
    
    int = zero/(digit1-9 *DIGIT) 
    
    minus = %x2D    ; - 
    
    plus = %x2B    ; + 
    
    zero = %x30    ; 0 
    
  2. Cho bất kỳ đầu vào __float128 "i" nào đã được printfed vào một chuỗi phù hợp với sản xuất ở trên "s" và sau đó "s" được scanfed trở lại vào một __floa t128 "j" - "i" phải giống bit "j" - nghĩa là không có thông tin nào bị mất. Đối với ít nhất một số giá trị, điều này là không thể (NaN, Infinity), danh sách đầy đủ của các giá trị đó là gì?

  3. Sẽ không có chuỗi nào khác thỏa mãn hai tiêu chí trên, ngắn hơn ứng cử viên.

Có chuỗi định dạng quadmath_snprintf thỏa mãn điều kiện trên (1, 3 và 2 khi có thể) không? Nếu vậy, nó là cái gì?

Giá trị của __float128 không thể biểu diễn đủ chính xác để đáp ứng điểm 2 bằng cách sản xuất ở trên là bao nhiêu? (ví dụ: Nan, +/- Infinity, v.v.) Làm cách nào để phát hiện xem một __float128 có đang giữ một trong các giá trị này không?

+0

Có một số thập phân vô hạn không thể được biểu diễn chính xác trong __float128. Bất kỳ số nào có nhiều hơn 34 chữ số có nghĩa. Trình định dạng định dạng của bạn tạo các chữ số ngẫu nhiên cho bất kỳ số tuyệt đối nào = = 1E5. Cách tiếp cận của bạn là thiếu sót, có thể bắt đầu bằng cách nghĩ rằng bạn cần __float128 để giải quyết vấn đề. –

+5

Thực tế là có một số thập phân vô hạn không thể biểu diễn chính xác trong __float128 là không liên quan, điểm 2 chỉ yêu cầu biểu diễn thập phân đủ chính xác sao cho khi đọc lại và làm tròn nó giống như những gì đã đi vào. nhận thức được trình định dạng định dạng không chính xác, câu hỏi yêu cầu một định dạng đúng. "Cách tiếp cận" của tôi là tốt và bạn không có ý tưởng những gì vấn đề tôi đang cố gắng để giải quyết. –

Trả lời

1

Nếu bạn đang sử dụng x86, thì loại GCC __float128 là phần mềm thực hiện định dạng IEEE 754-2008 binary128. Chuẩn IEEE 754 yêu cầu một nhị phân -> char -> nhị phân khứ hồi phục hồi giá trị ban đầu nếu biểu diễn ký tự chứa 36 chữ số (thập phân) quan trọng. Vì vậy, chuỗi định dạng "% .36Qg" nên làm điều đó.

Không bắt buộc vòng lặp NaN khôi phục giá trị bitwise ban đầu.

Đối với yêu cầu của bạn # 3, libquadmath không chứa mã cho loại định dạng "đại diện ngắn nhất" này, ví dụ: theo tinh thần của Steele & Giấy trắng hoặc mã của David Gay.

0

Trực giác của tôi cho tôi biết rằng phần nhị phân 0.1111 ... 1 (128 cái); cũng bằng 1-1/2 ** 128 sẽ tạo ra số lượng tràn lớn nhất khi chuyển đổi sang thập phân. Chuyển đổi giá trị đó thành số thập phân (Tôi không có gói bignum ngay bây giờ), đếm số chữ số, thêm 2-3 vào số đó và bạn nên an toàn. Tôi không có một bằng chứng toán học rằng điều này là đủ, mặc dù.

Nếu độ chính xác của I/O là quan trọng, tôi muốn xuất ra phao như một chuỗi hex. IO điểm nổi chính xác là khó để có được quyền, và thư viện có thể được lỗi trong sự tôn trọng đó.

+0

“0.1111 ...1 (128 cái) "không thể đại diện như một' __float128', nhưng thậm chí sửa chữa 128 thành 113 mà bạn có thể có nghĩa là, tôi không thấy tại sao số này phải là một trường hợp xấu nhất. Các đại diện thập phân của ứng cử viên xấu nhất trường hợp sẽ bắt đầu với một hàng đầu 1, thay vì một hàng đầu 9. –

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