import { reinterpretU64AsF64, reinterpretF64AsU64, reinterpretU32AsF32, reinterpretU16AsF16, } from './reinterpret.js'; export const kBit = { // Limits of int32 i32: { positive: { min: 0x0000_0000, // 0 max: 0x7fff_ffff, // 2147483647 }, negative: { min: 0x8000_0000, // -2147483648 max: 0x0000_0000, // 0 }, }, // Limits of uint32 u32: { min: 0x0000_0000, max: 0xffff_ffff, }, // Limits of f64 // Have to be stored as a BigInt hex value, since number is a f64 internally, // so 64-bit hex values are not guaranteed to be precisely representable. f64: { positive: { min: BigInt(0x0010_0000_0000_0000n), max: BigInt(0x7fef_ffff_ffff_ffffn), zero: BigInt(0x0000_0000_0000_0000n), subnormal: { min: BigInt(0x0000_0000_0000_0001n), max: BigInt(0x000f_ffff_ffff_ffffn), }, infinity: BigInt(0x7ff0_0000_0000_0000n), nearest_max: BigInt(0x7fef_ffff_ffff_fffen), less_than_one: BigInt(0x3fef_ffff_ffff_ffffn), pi: { whole: BigInt(0x4009_21fb_5444_2d18n), three_quarters: BigInt(0x4002_d97c_7f33_21d2n), half: BigInt(0x3ff9_21fb_5444_2d18n), third: BigInt(0x3ff0_c152_382d_7365n), quarter: BigInt(0x3fe9_21fb_5444_2d18n), sixth: BigInt(0x3fe0_c152_382d_7365n), }, e: BigInt(0x4005_bf0a_8b14_5769n), }, negative: { max: BigInt(0x8010_0000_0000_0000n), min: BigInt(0xffef_ffff_ffff_ffffn), zero: BigInt(0x8000_0000_0000_0000n), subnormal: { max: BigInt(0x8000_0000_0000_0001n), min: BigInt(0x800f_ffff_ffff_ffffn), }, infinity: BigInt(0xfff0_0000_0000_0000n), nearest_min: BigInt(0xffef_ffff_ffff_fffen), less_than_one: BigInt(0xbfef_ffff_ffff_ffffn), pi: { whole: BigInt(0xc009_21fb_5444_2d18n), three_quarters: BigInt(0xc002_d97c_7f33_21d2n), half: BigInt(0xbff9_21fb_5444_2d18n), third: BigInt(0xbff0_c152_382d_7365n), quarter: BigInt(0xbfe9_21fb_5444_2d18n), sixth: BigInt(0xbfe0_c152_382d_7365n), }, }, max_ulp: BigInt(0x7ca0_0000_0000_0000n), }, // Limits of f32 f32: { positive: { min: 0x0080_0000, max: 0x7f7f_ffff, zero: 0x0000_0000, subnormal: { min: 0x0000_0001, max: 0x007f_ffff, }, infinity: 0x7f80_0000, nearest_max: 0x7f7f_fffe, less_than_one: 0x3f7f_ffff, pi: { whole: 0x4049_0fdb, three_quarters: 0x4016_cbe4, half: 0x3fc9_0fdb, third: 0x3f86_0a92, quarter: 0x3f49_0fdb, sixth: 0x3f06_0a92, }, e: 0x402d_f854, }, negative: { max: 0x8080_0000, min: 0xff7f_ffff, zero: 0x8000_0000, subnormal: { max: 0x8000_0001, min: 0x807f_ffff, }, infinity: 0xff80_0000, nearest_min: 0xff7f_fffe, less_than_one: 0xbf7f_ffff, pi: { whole: 0xc04_90fdb, three_quarters: 0xc016_cbe4, half: 0xbfc9_0fdb, third: 0xbf86_0a92, quarter: 0xbf49_0fdb, sixth: 0xbf06_0a92, }, }, max_ulp: 0x7380_0000, }, // Limits of f16 f16: { positive: { min: 0x0400, max: 0x7bff, zero: 0x0000, subnormal: { min: 0x0001, max: 0x03ff, }, infinity: 0x7c00, nearest_max: 0x7bfe, less_than_one: 0x3bff, pi: { whole: 0x4248, three_quarters: 0x40b6, half: 0x3e48, third: 0x3c30, quarter: 0x3a48, sixth: 0x3830, }, e: 0x416f, }, negative: { max: 0x8400, min: 0xfbff, zero: 0x8000, subnormal: { max: 0x8001, min: 0x83ff, }, infinity: 0xfc00, nearest_min: 0xfbfe, less_than_one: 0xbbff, pi: { whole: 0xc248, three_quarters: 0xc0b6, half: 0xbe48, third: 0xbc30, quarter: 0xba48, sixth: 0xb830, }, }, max_ulp: 0x5000, }, // Uint32 representation of power(2, n) n = {0, ..., 31} // Stored as a JS `number` // {to0, ..., to31} ie. {0, ..., 31} powTwo: { to0: 0x0000_0001, to1: 0x0000_0002, to2: 0x0000_0004, to3: 0x0000_0008, to4: 0x0000_0010, to5: 0x0000_0020, to6: 0x0000_0040, to7: 0x0000_0080, to8: 0x0000_0100, to9: 0x0000_0200, to10: 0x0000_0400, to11: 0x0000_0800, to12: 0x0000_1000, to13: 0x0000_2000, to14: 0x0000_4000, to15: 0x0000_8000, to16: 0x0001_0000, to17: 0x0002_0000, to18: 0x0004_0000, to19: 0x0008_0000, to20: 0x0010_0000, to21: 0x0020_0000, to22: 0x0040_0000, to23: 0x0080_0000, to24: 0x0100_0000, to25: 0x0200_0000, to26: 0x0400_0000, to27: 0x0800_0000, to28: 0x1000_0000, to29: 0x2000_0000, to30: 0x4000_0000, to31: 0x8000_0000, }, // Int32 representation of of -1 * power(2, n) n = {0, ..., 31} // Stored as a JS `number` // {to0, ..., to31} ie. {0, ..., 31} negPowTwo: { to0: 0xffff_ffff, to1: 0xffff_fffe, to2: 0xffff_fffc, to3: 0xffff_fff8, to4: 0xffff_fff0, to5: 0xffff_ffe0, to6: 0xffff_ffc0, to7: 0xffff_ff80, to8: 0xffff_ff00, to9: 0xffff_fe00, to10: 0xffff_fc00, to11: 0xffff_f800, to12: 0xffff_f000, to13: 0xffff_e000, to14: 0xffff_c000, to15: 0xffff_8000, to16: 0xffff_0000, to17: 0xfffe_0000, to18: 0xfffc_0000, to19: 0xfff8_0000, to20: 0xfff0_0000, to21: 0xffe0_0000, to22: 0xffc0_0000, to23: 0xff80_0000, to24: 0xff00_0000, to25: 0xfe00_0000, to26: 0xfc00_0000, to27: 0xf800_0000, to28: 0xf000_0000, to29: 0xe000_0000, to30: 0xc000_0000, to31: 0x8000_0000, }, } as const; export const kValue = { // Limits of i64 i64: { positive: { min: BigInt(0n), max: BigInt(9223372036854775807n), }, negative: { min: BigInt(-9223372036854775808n), max: BigInt(0n), }, isOOB: (val: bigint): boolean => { return val > kValue.i64.positive.max || val < kValue.i64.negative.min; }, }, // Limits of i32 i32: { positive: { min: 0, max: 2147483647, }, negative: { min: -2147483648, max: 0, }, }, // Limits of u32 u32: { min: 0, max: 4294967295, }, // Limits of f64 f64: { positive: { min: reinterpretU64AsF64(kBit.f64.positive.min), max: reinterpretU64AsF64(kBit.f64.positive.max), zero: reinterpretU64AsF64(kBit.f64.positive.zero), subnormal: { min: reinterpretU64AsF64(kBit.f64.positive.subnormal.min), max: reinterpretU64AsF64(kBit.f64.positive.subnormal.max), }, infinity: reinterpretU64AsF64(kBit.f64.positive.infinity), nearest_max: reinterpretU64AsF64(kBit.f64.positive.nearest_max), less_than_one: reinterpretU64AsF64(kBit.f64.positive.less_than_one), pi: { whole: reinterpretU64AsF64(kBit.f64.positive.pi.whole), three_quarters: reinterpretU64AsF64(kBit.f64.positive.pi.three_quarters), half: reinterpretU64AsF64(kBit.f64.positive.pi.half), third: reinterpretU64AsF64(kBit.f64.positive.pi.third), quarter: reinterpretU64AsF64(kBit.f64.positive.pi.quarter), sixth: reinterpretU64AsF64(kBit.f64.positive.pi.sixth), }, e: reinterpretU64AsF64(kBit.f64.positive.e), }, negative: { max: reinterpretU64AsF64(kBit.f64.negative.max), min: reinterpretU64AsF64(kBit.f64.negative.min), zero: reinterpretU64AsF64(kBit.f64.negative.zero), subnormal: { max: reinterpretU64AsF64(kBit.f64.negative.subnormal.max), min: reinterpretU64AsF64(kBit.f64.negative.subnormal.min), }, infinity: reinterpretU64AsF64(kBit.f64.negative.infinity), nearest_min: reinterpretU64AsF64(kBit.f64.negative.nearest_min), less_than_one: reinterpretU64AsF64(kBit.f64.negative.less_than_one), // -0.999999940395 pi: { whole: reinterpretU64AsF64(kBit.f64.negative.pi.whole), three_quarters: reinterpretU64AsF64(kBit.f64.negative.pi.three_quarters), half: reinterpretU64AsF64(kBit.f64.negative.pi.half), third: reinterpretU64AsF64(kBit.f64.negative.pi.third), quarter: reinterpretU64AsF64(kBit.f64.negative.pi.quarter), sixth: reinterpretU64AsF64(kBit.f64.negative.pi.sixth), }, }, max_ulp: reinterpretU64AsF64(kBit.f64.max_ulp), }, // Limits of f32 f32: { positive: { min: reinterpretU32AsF32(kBit.f32.positive.min), max: reinterpretU32AsF32(kBit.f32.positive.max), zero: reinterpretU32AsF32(kBit.f32.positive.zero), subnormal: { min: reinterpretU32AsF32(kBit.f32.positive.subnormal.min), max: reinterpretU32AsF32(kBit.f32.positive.subnormal.max), }, infinity: reinterpretU32AsF32(kBit.f32.positive.infinity), nearest_max: reinterpretU32AsF32(kBit.f32.positive.nearest_max), less_than_one: reinterpretU32AsF32(kBit.f32.positive.less_than_one), pi: { whole: reinterpretU32AsF32(kBit.f32.positive.pi.whole), three_quarters: reinterpretU32AsF32(kBit.f32.positive.pi.three_quarters), half: reinterpretU32AsF32(kBit.f32.positive.pi.half), third: reinterpretU32AsF32(kBit.f32.positive.pi.third), quarter: reinterpretU32AsF32(kBit.f32.positive.pi.quarter), sixth: reinterpretU32AsF32(kBit.f32.positive.pi.sixth), }, e: reinterpretU32AsF32(kBit.f32.positive.e), // The positive pipeline-overridable constant with the smallest magnitude // which when cast to f32 will produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL. first_non_castable_pipeline_override: reinterpretU32AsF32(kBit.f32.positive.max) / 2 + 2 ** 127, // The positive pipeline-overridable constant with the largest magnitude // which when cast to f32 will not produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL last_castable_pipeline_override: reinterpretU64AsF64( reinterpretF64AsU64(reinterpretU32AsF32(kBit.f32.positive.max) / 2 + 2 ** 127) - BigInt(1) ), }, negative: { max: reinterpretU32AsF32(kBit.f32.negative.max), min: reinterpretU32AsF32(kBit.f32.negative.min), zero: reinterpretU32AsF32(kBit.f32.negative.zero), subnormal: { max: reinterpretU32AsF32(kBit.f32.negative.subnormal.max), min: reinterpretU32AsF32(kBit.f32.negative.subnormal.min), }, infinity: reinterpretU32AsF32(kBit.f32.negative.infinity), nearest_min: reinterpretU32AsF32(kBit.f32.negative.nearest_min), less_than_one: reinterpretU32AsF32(kBit.f32.negative.less_than_one), // -0.999999940395 pi: { whole: reinterpretU32AsF32(kBit.f32.negative.pi.whole), three_quarters: reinterpretU32AsF32(kBit.f32.negative.pi.three_quarters), half: reinterpretU32AsF32(kBit.f32.negative.pi.half), third: reinterpretU32AsF32(kBit.f32.negative.pi.third), quarter: reinterpretU32AsF32(kBit.f32.negative.pi.quarter), sixth: reinterpretU32AsF32(kBit.f32.negative.pi.sixth), }, // The negative pipeline-overridable constant with the smallest magnitude // which when cast to f32 will produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL. first_non_castable_pipeline_override: -( reinterpretU32AsF32(kBit.f32.positive.max) / 2 + 2 ** 127 ), // The negative pipeline-overridable constant with the largest magnitude // which when cast to f32 will not produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL. last_castable_pipeline_override: -reinterpretU64AsF64( reinterpretF64AsU64(reinterpretU32AsF32(kBit.f32.positive.max) / 2 + 2 ** 127) - BigInt(1) ), }, max_ulp: reinterpretU32AsF32(kBit.f32.max_ulp), emax: 127, }, // Limits of i16 i16: { positive: { min: 0, max: 32767, }, negative: { min: -32768, max: 0, }, }, // Limits of u16 u16: { min: 0, max: 65535, }, // Limits of f16 f16: { positive: { min: reinterpretU16AsF16(kBit.f16.positive.min), max: reinterpretU16AsF16(kBit.f16.positive.max), zero: reinterpretU16AsF16(kBit.f16.positive.zero), subnormal: { min: reinterpretU16AsF16(kBit.f16.positive.subnormal.min), max: reinterpretU16AsF16(kBit.f16.positive.subnormal.max), }, infinity: reinterpretU16AsF16(kBit.f16.positive.infinity), nearest_max: reinterpretU16AsF16(kBit.f16.positive.nearest_max), less_than_one: reinterpretU16AsF16(kBit.f16.positive.less_than_one), pi: { whole: reinterpretU16AsF16(kBit.f16.positive.pi.whole), three_quarters: reinterpretU16AsF16(kBit.f16.positive.pi.three_quarters), half: reinterpretU16AsF16(kBit.f16.positive.pi.half), third: reinterpretU16AsF16(kBit.f16.positive.pi.third), quarter: reinterpretU16AsF16(kBit.f16.positive.pi.quarter), sixth: reinterpretU16AsF16(kBit.f16.positive.pi.sixth), }, e: reinterpretU16AsF16(kBit.f16.positive.e), // The positive pipeline-overridable constant with the smallest magnitude // which when cast to f16 will produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL. first_non_castable_pipeline_override: reinterpretU16AsF16(kBit.f16.positive.max) / 2 + 2 ** 15, // The positive pipeline-overridable constant with the largest magnitude // which when cast to f16 will not produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL last_castable_pipeline_override: reinterpretU64AsF64( reinterpretF64AsU64(reinterpretU16AsF16(kBit.f16.positive.max) / 2 + 2 ** 15) - BigInt(1) ), }, negative: { max: reinterpretU16AsF16(kBit.f16.negative.max), min: reinterpretU16AsF16(kBit.f16.negative.min), zero: reinterpretU16AsF16(kBit.f16.negative.zero), subnormal: { max: reinterpretU16AsF16(kBit.f16.negative.subnormal.max), min: reinterpretU16AsF16(kBit.f16.negative.subnormal.min), }, infinity: reinterpretU16AsF16(kBit.f16.negative.infinity), nearest_min: reinterpretU16AsF16(kBit.f16.negative.nearest_min), less_than_one: reinterpretU16AsF16(kBit.f16.negative.less_than_one), // -0.9996 pi: { whole: reinterpretU16AsF16(kBit.f16.negative.pi.whole), three_quarters: reinterpretU16AsF16(kBit.f16.negative.pi.three_quarters), half: reinterpretU16AsF16(kBit.f16.negative.pi.half), third: reinterpretU16AsF16(kBit.f16.negative.pi.third), quarter: reinterpretU16AsF16(kBit.f16.negative.pi.quarter), sixth: reinterpretU16AsF16(kBit.f16.negative.pi.sixth), }, // The negative pipeline-overridable constant with the smallest magnitude // which when cast to f16 will produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL. first_non_castable_pipeline_override: -( reinterpretU16AsF16(kBit.f16.positive.max) / 2 + 2 ** 15 ), // The negative pipeline-overridable constant with the largest magnitude // which when cast to f16 will not produce infinity. This comes from WGSL // conversion rules and the rounding rules of WebIDL. last_castable_pipeline_override: -reinterpretU64AsF64( reinterpretF64AsU64(reinterpretU16AsF16(kBit.f16.positive.max) / 2 + 2 ** 15) - BigInt(1) ), }, max_ulp: reinterpretU16AsF16(kBit.f16.max_ulp), emax: 15, }, // Limits of i8 i8: { positive: { min: 0, max: 127, }, negative: { min: -128, max: 0, }, }, // Limits of u8 u8: { min: 0, max: 255, }, } as const;