2010-02-12 43 views
10

Tôi đang duy trì một chương trình lấy dữ liệu từ chương trình PDP-11 (được mô phỏng) và đặt nó vào một hệ thống dựa trên Windows hiện đại. Chúng tôi đang gặp sự cố với một số giá trị dữ liệu được báo cáo là "1. # QNAN" và cũng "1. # QNB". Khách hàng gần đây đã tiết lộ rằng các giá trị 'xấu' trong chương trình PDP-11 được biểu thị bằng 2 từ 16 bit với tất cả các bit được đặt trừ từ đầu tiên. Tôi nghĩ rằng đó là khi chúng tôi cố gắng chuyển đổi chúng sang IEEE nổi mà chúng tôi đang nhận được các lỗi.Liệu C++ này có chuyển đổi PDP-11 thành IEEE?

Tôi đã tìm thấy mã bên dưới được sử dụng để chuyển đổi các giá trị PDP-11 thành IEEE. Tôi không liên lạc với sự phức tạp của các đại diện điểm nổi nhưng điều này có vẻ hơi đơn giản với tôi! Điều này thực sự có thể chuyển đổi định dạng PDP-11 sang IEEE không?

// ---------------------------------------------------------------- cnvPDPfloat 
// CNVPDPFLOAT 
// ---------------------------------------------------------------------------- 
// 
// Converts PDP11 float (two 16-bit words) into IEEE float 
// 
// PDP11 and IEEE floats have same layout so can be mapped onto eachother. 
// But PDP11 exponent must have 2 subtracted for IEEE. Or just divide by 4. 
// 
float cnvPDPfloat(PDP11Float input) 
{ 
union 
{ 
    unsigned long pdp11; 
    float ieee; 
} uFloat; 

uFloat.pdp11 = (input.word[0] << 16) + input.word[1]; 

return (uFloat.ieee/(float) 4.0); 
} 

--- Alistair.

+3

1 chỉ vì thực tế là bạn phải duy trì PDP-11 mã. –

+0

Lưu ý rằng '1. # QNB' đơn giản là' 1. # QNAN' "được làm tròn" thành 4 vị trí. (Tôi không thể tìm thấy câu hỏi SO trước đó về trường hợp phổ biến hơn của '# INF' đang được" làm tròn "thành' # J'.) –

Trả lời

0

PDP-11 sử dụng một biểu diễn hỗn hợp-endian cho các số dấu phẩy động. vì vậy phần này của mã

uFloat.pdp11 = (input.word[0] << 16) + input.word[1]; 

là chính xác nếu dữ liệu của bạn chưa được đổi từ trước khi bạn nhận được.

Tài liệu này cung cấp cho các chi tiết của các đại diện cho rất nhiều định dạng dấu chấm động khác nhau http://www.quadibloc.com/comp/cp0201.htm

Nó nói rằng t PDP-11/VAX sử dụng 128 ký hiệu dư thừa cho số mũ. trong khi IEEE 754 sử dụng ký hiệu 126 dư thừa, vì vậy nếu nó đúng, chia cho 4 có vẻ là cách chính xác để điều chỉnh số mũ.

Tuy nhiên, Wikipedia nói rằng độ lệch số mũ cho IEEE 754 là 127, không phải 126. Vì vậy, tài liệu trên đang sử dụng ký hiệu lạ hoặc không chính xác. Có thể bạn cần chia cho 2 thay vì bằng 4.

1

Từ this page, định dạng PDP-11 giống với định dạng điểm nổi IEEE-754 ngoại trừ số mũ được thiên vị 128 trong PDP-11, trong khi nó bị sai lệch 127 trong IEEE-754. Vì vậy, bạn cần phải chia cho 2.0 và không 4.0. Điều này không chăm sóc NaN và infinities, nhưng từ tìm kiếm google của tôi, có vẻ như PDP-11 đã không có những người.

Bạn cũng sẽ gặp sự cố với tràn. Các định dạng PDP tràn trước đó, nhưng tôi giả định rằng đó là OK vì bạn không thể thực sự làm bất cứ điều gì một khi một số đã bị tràn.

+0

sai. Nó sẽ được chia cho 4. Xem câu trả lời của tôi dưới đây. – marcin

0

Ngoài NaN và Inf, bạn cũng có thể gặp vấn đề với việc chuyển đổi các giá trị bất thường. Tôi không biết liệu PDP-11 có hỗ trợ những điều này hay không, nhưng IEEE 754 nói rằng khi trường số mũ là 0, thì các con số là các biến thể, nghĩa là hàm 1 dẫn đầu trong trường mantissa trở thành 0. Theo cách này, hội tụ dần dần về 0 khi số đang giảm.

@John - Chuẩn IEEE 754 tuyên bố rằng độ lệch số mũ là 127, không phải 126. Wiki là đúng và tham chiếu khác là sai. Vì vậy, tỷ lệ sẽ là 2,0.

2

Mã này không kiểm tra giá trị undefined, sạch-zerobẩn-zero, nhưng chia cho 4, thảo luận trong câu trả lời khác, là tốt. OP có thể biết điều đó bởi vì họ sẽ phát hiện ra nếu kết quả luôn sai. Xu hướng mũ cũng nhầm lẫn cho tôi ngày hôm nay, vì vậy tôi sẽ trích dẫn những gì tôi vừa đọc trong tài liệu tốt này: Binary floats with hidden bit:

Lúc đầu các bit ẩn được đưa ra một vị trí khác. IEEE giả định bit này trước khoảng thời gian phân đoạn và Digital giả định nó ngay sau khoảng thời gian đó. Theo IEEE phần hiển thị của mantissa ('visman') bắt đầu ngay lập tức sau giai đoạn, trong khi theo Kỹ thuật số nó bắt đầu đằng sau bit ẩn. Do đó, phạm vi giá trị của tổng mantissa là:

IEEE:  1.0 =< (1.visman) < 2.0 
Digital: 0.5 =< (0.1 visman) < 1.0 

Tại thứ hai thừa-sai số trong các ký hiệu của số mũ khác nhau. [by 1 ...]

Cả hai tác động cùng nhau làm cho mẫu bit trong IEEE-float đại diện cho một số có kích thước gấp bốn lần giá trị cùng một mẫu trong chữ nổi kỹ thuật số.

cũng Điều này giải thích tại sao một số tài liệu tham khảo nêu rằng IEEE thiên vị là 126.

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