利用者:Ef3/Bfloat16Array
表示
< 利用者:Ef3
/**
* Bfloat16Array - A polyfill for Brain Floating Point 16-bit arrays
*
* Bfloat16 format:
* - 1 bit: sign
* - 8 bits: exponent
* - 7 bits: mantissa
*
* This is different from IEEE 754 half-precision (Float16) which uses:
* - 1 bit: sign
* - 5 bits: exponent
* - 10 bits: mantissa
*/
class Bfloat16Array extends Uint16Array {
static get [Symbol.species]() {
return Bfloat16Array;
}
// float32からbfloat16に変換
static _float32ToBFloat16(value) {
const float32 = new Float32Array(1);
const uint32 = new Uint32Array(float32.buffer);
float32[0] = value;
return uint32[0] >>> 16;
}
// bfloat16からfloat32に変換
static _bfloat16ToFloat32(value) {
const uint32 = new Uint32Array(1);
uint32[0] = value << 16;
const float32 = new Float32Array(uint32.buffer);
return float32[0];
}
// インデックスアクセス (getter)
get(index) {
return Bfloat16Array._bfloat16ToFloat32(this[index]);
}
// インデックスアクセス (setter)
set(index, value) {
super[index] = Bfloat16Array._float32ToBFloat16(value);
}
// イテレータをオーバーライドしてfloat32値を返す
*[Symbol.iterator]() {
for (let i = 0; i < this.length; i++) {
yield this.get(i);
}
}
// mapメソッドをオーバーライド
map(fn) {
const result = new (this.constructor[Symbol.species])(this.length);
for (let i = 0; i < this.length; i++) {
result.set(i, fn(this.get(i), i, this));
}
return result;
}
// sliceメソッドをオーバーライド
slice(start, end) {
const sliced = super.slice(start, end);
return new this.constructor(sliced.buffer);
}
}
// Usage example:
function testBfloat16Array() {
console.log("Testing Bfloat16Array...");
// Create a new array with 5 elements
const bf16 = new Bfloat16Array(5);
// Set some values
bf16[0] = 1.0;
bf16[1] = 1234.5678;
bf16[2] = 3.14159265359;
bf16[3] = 2.71828;
bf16[4] = 1.0e20;
console.log("Array values:");
for (let i = 0; i < bf16.length; i++) {
console.log(`bf16[${i}] = ${bf16[i]}`);
}
// Compare with Float32Array to show precision differences
const f32 = new Float32Array([1.0, 1234.5678, 3.14159265359, 2.71828, 1.0e20]);
console.log("\nComparison with Float32Array (precision differences):");
for (let i = 0; i < bf16.length; i++) {
console.log(`bfloat16: ${bf16[i]} vs float32: ${f32[i]}`);
}
// Test array methods
console.log("\nTesting array methods:");
console.log("forEach:");
bf16.forEach((value, index) => console.log(`${index}: ${value}`));
console.log("\nmap (multiply by 2):");
const doubled = bf16.map(x => x * 2);
for (let i = 0; i < doubled.length; i++) {
console.log(`doubled[${i}] = ${doubled[i]}`);
}
// Test subarray
console.log("\nTesting subarray:");
const subarray = bf16.subarray(1, 4);
for (let i = 0; i < subarray.length; i++) {
console.log(`subarray[${i}] = ${subarray[i]}`);
}
return "Bfloat16Array test completed";
}
// Run tests if script is executed directly
if (typeof require !== 'undefined' && require.main === module) {
testBfloat16Array();
}