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.
bạn không có sẵn đơn vị 8087 để thực hiện công việc? –
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ể. –
@ 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