DataView.setInt32() คืออะไร
เมธอด DataView.prototype.setInt32() ใช้สำหรับ เขียนค่าจำนวนเต็มมีเครื่องหมาย 32-bit (signed 32-bit integer) ลงในตำแหน่งที่กำหนดใน DataView ค่าที่เขียนได้จะอยู่ในช่วง -2,147,483,648 ถึง 2,147,483,647 (-2^31 ถึง 2^31-1)
ไวยากรณ์ (Syntax)
dataView.setInt32(byteOffset, value [, littleEndian])
byteOffset- ตำแหน่งเริ่มต้นในหน่วยไบต์ (0-indexed)value- ค่าที่จะเขียน (-2147483648 ถึง 2147483647)littleEndian(optional) -true= little-endian,false= big-endian (default:false)
คืนค่า: undefined
ตัวอย่างการใช้งาน
ตัวอย่างที่ 1: การเขียนและอ่านค่าพื้นฐาน
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setInt32(0, 36274722); // big-endian default
console.log(view.getInt32(0)); // 36274722
ตัวอย่างที่ 2: Endianness Handling
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
const value = 0x12345678; // 305419896
view.setInt32(0, value, false); // big-endian
view.setInt32(4, value, true); // little-endian
console.log('BE:', view.getInt32(0, false).toString(16)); // 12345678
console.log('LE:', view.getInt32(4, true).toString(16)); // 12345678
ตัวอย่างที่ 3: ค่าลบและ Overflow
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setInt32(0, -1); // 0xFFFFFFFF
view.setInt32(4, -2147483648); // 0x80000000 (min int32)
view.setInt32(4, 2147483648); // overflow -> -2147483648
console.log(view.getInt32(0)); // -1
console.log(view.getInt32(4)); // -2147483648
ตัวอย่างที่ 4: การแปลงค่า Float
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setInt32(0, 554.36); // truncate -> 554
console.log(view.getInt32(0)); // 554
ตัวอย่างที่ 5: Unix Timestamp Packing
function packTimestamp(date) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
// Unix timestamp ในวินาที (32-bit signed จะหมดอายุปี 2038)
const timestamp = Math.floor(date.getTime() / 1000);
view.setInt32(0, timestamp, false); // big-endian for network
return buffer;
}
function unpackTimestamp(buffer) {
const view = new DataView(buffer);
const timestamp = view.getInt32(0, false);
return new Date(timestamp * 1000);
}
const now = new Date();
const packed = packTimestamp(now);
console.log(unpackTimestamp(packed).toISOString());
ตัวอย่างที่ 6: อ่านค่าที่ยังไม่ได้ตั้งค่า
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
console.log(view.getInt32(0)); // 0
Year 2038 Problem (Y2K38)
Signed 32-bit integer สำหรับ Unix timestamp จะล้น (overflow) ในวันที่ 19 มกราคม 2038 03:14:07 UTC (2,147,483,647 วินาทีจาก epoch) หลังจากนั้นค่าจะกลายเป็นลบ (แทนวันที่ในปี 1901)
// ตัวอย่างปัญหา Y2038
const maxInt32 = 2147483647;
const date = new Date(maxInt32 * 1000);
console.log(date.toUTCString()); // Tue, 19 Jan 2038 03:14:07 GMT
// โซลูชัน: ใช้ 64-bit (BigInt64Array) หรือ Float64
const buffer64 = new ArrayBuffer(8);
const view64 = new DataView(buffer64);
view64.setBigInt64(0, BigInt(Date.now()), false); // 64-bit timestamp
กรณีการใช้งานทั่วไป
- Network protocols: Signed 32-bit fields ใน protocol headers
- File formats: PNG (chunk lengths สามารถเป็น signed), MP4, ZIP
- Unix timestamps (legacy): 32-bit time_t (ระวัง Y2038)
- Database storage: Binary integer serialization
- Game networking: Entity IDs, coordinates (signed)
- WebAssembly interop: รับส่ง i32
กรณีพิเศษและข้อผิดพลาด
- โยน
RangeErrorหากbyteOffsetติดลบ หรือbyteOffset + 4 > byteLength - ค่า
valueจะถูกแปลงด้วยToInt32(modulo 2^32 แล้ว interpret เป็น signed) - Endianness ต้องตรงกับที่อ่าน (getInt32)
- สำหรับ timestamp ใหม่ ควรใช้ 64-bit (BigInt64Array หรือ Float64)