Теперь попробуем нашу функцию с числами в одном типе, но записанным с помощью разных систем счисления.



fn main() {

let a: u16 = 0b10000000000;

let b: u16 = 0o2000;

let c: u16 = 1024;

let d: u16 = 0x400;



print_bytes_in_binary(&a.to_ne_bytes()); // 0000000000000100

print_bytes_in_binary(&b.to_ne_bytes()); // 0000000000000100

print_bytes_in_binary(&c.to_ne_bytes()); // 0000000000000100

print_bytes_in_binary(&d.to_ne_bytes()); // 0000000000000100

}




Все числа в памяти представлены идентично.



На самом деле, похожую функцию мы можем сделать и в JS, но тут есть оговорка, что мы не знаем про "внутреннее" устройство VM. Окей, предположим, что раз у нас Number, то это формат IEEE-754 Double.



getDoubleStr(0xA); // 0000000000000000000000000000000000000000000000000010010001000000

getDoubleStr(10); // 0000000000000000000000000000000000000000000000000010010001000000



console.log(getDoubleStr(0xA) === getDoubleStr(10)); // true



function getDoubleStr(num) {

const data = new DataView(new ArrayBuffer(8));

data.setFloat64(0, num, true); // Little-Endian используется в x86



let bits = '';



for (let i = 0; i < 8; i++) {

const byte = data.getUint8(i).toString(2).padStart(8, '0');

bits += byte;

}



return bits;

}




Все эти примеры должны подвести нас к очень важной мысли: компьютер не "наделяет смыслом" данные - для него всё бессмысленный поток нулей и единиц. Смысл данным дает программист: вот я могу написать программу, которая на основе этих байтов выводит изображение на экран, а вот эти же данные я представляю одним большим числом...



Всем базы! 🚀