2011-08-06 36 views
7

Tôi đang cố chuyển đổi số điểm nổi chính xác mở rộng 80 bit (trong bộ đệm) thành gấp đôi. Bộ đệm về cơ bản chứa nội dung của thanh ghi x87.Điểm nổi 80 bit và các số phụ bất thường

This question đã giúp tôi bắt đầu vì tôi không quen với tiêu chuẩn IEEE. Dù sao, tôi đang đấu tranh để tìm thông tin hữu ích về các số không bình thường (hoặc không chuẩn hóa) ở định dạng 80 bit. Những gì tôi biết là không giống float32 hoặc float64, nó không có một bit ẩn trong phần định nghĩa (không có ngụ ý bổ sung 1.0), vì vậy một cách để biết một số có được chuẩn hóa hay không là kiểm tra xem bit cao nhất trong mantissa là bộ. Điều đó để lại cho tôi câu hỏi sau:

Từ những gì wikipedia cho tôi biết, float32 và float64 biểu thị số không bình thường với số mũ (sai) là 0 và một số không khác.

  • Điều đó cho tôi biết điều gì ở phao 80 bit?
  • Có thể nổi 80 bit với mantissa < 1.0 thậm chí có số mũ khác không?
  • Cách khác, có thể nổi 80 bit với số mũ bằng 0 thậm chí có một giá trị> = 1.0?

EDIT: Tôi đoán câu hỏi boils xuống:

Tôi có thể mong đợi FPU để khử trùng số mũ và chút mantissa cao nhất trong thanh ghi x87?

Nếu không, loại kết quả chuyển đổi sẽ như thế nào? Tôi có nên bỏ qua các số mũ hoàn toàn trong trường hợp đó? Hay là qNaN?

EDIT:

Tôi đọc phần FPU trong cuốn hướng dẫn Intel (Intel® 64 và IA-32 Kiến trúc Manual Software Developer, Tập 1: Cơ bản Kiến trúc) mà là ít đáng sợ hơn là tôi đã lo sợ . Khi nó quay ra các giá trị sau không được định nghĩa:

  • mũ == 0 + mantissa với bit cao nhất thiết
  • mũ = 0 + mantissa mà không có chút cao nhất thiết lập

Nó doesn! không đề cập đến nếu các giá trị này có thể xuất hiện trong tự nhiên, cũng không phải nếu chúng được chuyển đổi nội bộ. Vì vậy, tôi thực sự đã xóa sạch Ollydbg và tự thiết lập các bit trong thanh ghi x87. tôi crafted ST (0) để chứa tất cả các bit đặt trong số mũ và một mantissa của 0. Sau đó, tôi đã làm cho nó thực hiện

FSTP QWORD [ESP] 
FLD QWORD [ESP] 

Giá trị bảo quản ở [ESP] được chuyển đổi thành một tín hiệu NaN. Sau FLD, ST(0) chứa NaN yên tĩnh.

Tôi đoán câu trả lời cho câu hỏi của tôi. Tôi chấp nhận giải pháp J-16 SDiZ bởi vì nó là giải pháp chuyển tiếp thẳng thắn nhất (mặc dù nó không giải thích rõ ràng một số chi tiết tốt hơn).

Dù sao, trường hợp đã được giải quyết. Cảm ơn tất cả mọi người.

+0

bạn không có sẵn đơn vị 8087 để thực hiện công việc? –

+0

Có lẽ sẽ cần phải hỏi ai đó biết lắp ráp để đưa nó trở lại trong một học kỳ được liên kết với một biến cụ thể. –

+0

@ David Heffernan: Tôi làm nhưng C++ (do đó thẻ) không đảm bảo rằng đôi dài có kích thước 80 bit. Trong thực tế, VC++ định nghĩa dài gấp đôi và gấp đôi để có cùng kích thước (64 bit). Inline assembler có vẻ như là cách duy nhất để có được một chuyển đổi hoàn hảo (có mã trong câu hỏi tôi liên kết) nhưng tôi thích sử dụng đồng bằng C++, đặc biệt là vì không có lắp ráp nội tuyến trong VC++ 64-bit. – pezcode

Trả lời

3

Hãy thử SoftFloat thư viện, nó có floatx80_to_float32, floatx80_to_float64floatx80_to_float128. Phát hiện định dạng gốc, hành động phù hợp.

3

Sự cố khi tìm thông tin về số 80 bit phụ bình thường có thể là do 8087 không sử dụng bất kỳ sự chuẩn hóa đặc biệt nào cho chúng. Tìm thấy trang này trên trang MSDNs trên Type float (C):

Giá trị được liệt kê trong bảng này chỉ áp dụng cho các số dấu phẩy động chuẩn hóa ; số dấu phẩy động không chuẩn hóa có giá trị tối thiểu nhỏ hơn . Lưu ý rằng các số được lưu giữ trong sổ đăng ký 80x87 luôn được thể hiện dưới dạng chuẩn hóa 80 bit; Các số chỉ có thể là được biểu thị dưới dạng không chuẩn hóa khi được lưu trữ trong các biến số dấu phẩy động 32 bit hoặc 64 bit (các biến kiểu float và loại dài).

Sửa

Trên đây có thể là đúng đối với cách Microsoft tận dụng các FPU đăng ký. Tìm thấy một nguồn mà cho biết điều này:

FPU Data types:

Các 80x87 FPU thường lưu trữ các giá trị trong một định dạng bình thường. Khi số dấu phẩy động được chuẩn hóa, H.O. bit luôn là một. Trong các định dạng điểm nổi 32 và 64 bit, 80x87 không thực sự là lưu trữ bit này, 80x87 luôn luôn giả định rằng đó là một. Do đó, 32 và 64 bit số dấu phẩy động luôn được chuẩn hóa. Trong định dạng dấu phẩy động 80 bit chính xác mở rộng , 80x87 không giả định rằng H.O. bit của mantissa là một, H.O. bit của số xuất hiện như là một phần của chuỗi bit.

Giá trị được chuẩn hóa cung cấp độ chính xác cao nhất cho số lượng bit nhất định. Tuy nhiên, có một số lượng lớn các giá trị không chuẩn hóa mà chúng tôi có thể đại diện với định dạng 80 bit. Các giá trị này rất gần với bằng không và biểu thị tập hợp các giá trị có chú thích H.O. bit không phải là không. Các FPU 80x87 hỗ trợ một dạng đặc biệt 80 bit được gọi là các giá trị không chuẩn hóa.

+2

Tôi nghĩ động cơ ban đầu của FPU 80 bit là bạn có thể thực hiện các hoạt động 64 bit với độ chính xác cao hơn, nhưng bạn luôn mong đợi giao diện thông qua các phao 64 bit. Trong trường hợp đó, bạn sẽ không bao giờ tạo ra các float nổi 80 bit, bởi vì ngay cả float nhỏ nhất 64 bit vẫn là một float 80 bit bình thường. –

+0

@Kerrek SB: Điều đó không có nghĩa là không thể cho nó ăn hai phao 64 bit, tính toán một chút và nhận được kết quả là thậm chí 80 bit không thể giữ ở dạng chuẩn hóa. – pezcode

+0

@pezcode: chắc chắn, nhưng quay trở lại bất kỳ giá trị bất thường 80 bit nào sẽ bằng không trong biểu diễn 64 bit, do đó, đó không phải là vấn đề, chỉ là phần dưới. –

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