2013-04-19 73 views
7

Tôi đang cố gắng đọc tệp nhị phân trong C#, nhưng tôi đang gặp phải sự cố. tôi tuyên bố như sau:Số thập lục phân C#

public static readonly UInt32 NUMBER = 0XCAFEBABE; 

Sau đó, khi đọc từ đầu của tập tin tôi yêu cầu để đọc 4 byte đầu tiên (đã thử nhiều cách khác nhau, nhưng điều này là đơn giản nhất):

UInt32 num = in_.ReadUInt32(); // in_ is a BinaryReader 

Trong khi tôi có rằng 4 byte là CA, FE, BA và BE (trong hex) trong khi chuyển đổi chúng thành UInt Tôi nhận được các giá trị khác nhau. SỐ là 3405691582, num là 3199925962. Tôi cũng đã cố gắng để làm điều này:

byte[] f2 = {0xCA, 0xFE, 0xBA, 0xBE}; 

và kết quả làm BitConverter.ToUInt32(new byte[]{0xCA, 0xFE, 0xBA, 0xBE},0) là 3199925962.

bất cứ ai có thể giúp tôi?

nhờ

+0

Các bạn đã thử 'byte [ ] f2 = {0xBE, 0xBA, 0xFE, 0xCA}; '? http://en.wikipedia.org/wiki/Endianness – I4V

+3

'CAFEBABE', đó là số hot: D – Nolonar

Trả lời

6

Đây là vì ít endianness của máy tính của bạn. Xem tài sản BitConverter.IsLittleEndian để kiểm tra điều này.

Về cơ bản, các số được lưu trữ theo thứ tự byte ngược, so với cách bạn viết chúng xuống. Chúng tôi viết số quan trọng nhất ở bên trái, nhưng PC (ít cuối cùng) lưu trữ ít nhất byte đáng kể ở bên trái. Do đó, kết quả bạn nhận được thực sự là 0xBEBAFECA (3199925962 thập phân) chứ không phải những gì bạn mong đợi.

Bạn có thể chuyển đổi sử dụng hoạt động chút thay đổi:

uint value = (f2[0] << 24) | (f2[1] << 16) | (f2[2] << 8) | f2[3]; 

Có nhiều cách hơn để chuyển đổi, bao gồm IPAddress.NetworkToHostOrder như I4V chỉ ra, f2.Reverse() vv

Đối với mã cụ thể của bạn, tôi tin rằng điều này sẽ là thiết thực nhất:

uint num = (uint)IPAddress.NetworkToHostOrder(in_.ReadInt32()); 

Tuy nhiên, điều này có thể dẫn đến gián đoạn số học, do đó có thể gây ra vấn đề với wit h a /checked compiler option or checked keyword (không phổ biến lắm).

Nếu bạn muốn để đối phó với những tình huống này và nhận được mã thậm chí sạch, bọc nó trong một phương pháp khuyến nông:

public static uint ReadUInt32NetworkOrder(this BinaryReader reader) 
{ 
    unchecked 
    { 
     return (uint)IPAddress.NetworkToHostOrder(reader.ReadInt32());  
    } 
} 
+0

' IPAddress.NetworkToHostOrder' – I4V

+0

@ I4V Tôi quên mất phương pháp đó. Bất cứ ai đặt điều đó trong lớp 'IPAddress' ... Thật không may là không có phiên bản UInt32 nào của phương thức, do đó sẽ yêu cầu một số không quan trọng. – Thorarin

+0

'IPAddress.NetworkToHostOrder' chuyển đổi giữa tính xác thực của địa chỉ IP trong gói giao thức IP (lớn-endian) và thứ tự máy chủ (nhỏ-endian trên x86, nhưng có thể là big-endian trên các kiến ​​trúc khác như ARM). Đừng đi vào thói quen sử dụng chức năng này để đảo ngược tính cuối cùng, bởi vì nó sẽ không hoạt động đa nền tảng. – smead

3

Đó là những gì được gọi là byte order:

var result1 = BitConverter.ToUInt32(new byte[] { 0xCA, 0xFE, 0xBA, 0xBE }, 0); 
//3199925962 

var result2 = BitConverter.ToUInt32(new byte[] { 0xBE, 0xBA, 0xFE, 0xCA }, 0); 
//3405691582 
Các vấn đề liên quan