1 line
16 KiB
JavaScript
1 line
16 KiB
JavaScript
const base={};base.Int64=class Int64{constructor(low,high){this.low=low|0;this.high=high|0}static create(value){if(isNaN(value)){return base.Int64.zero}if(value<=-0x8000000000000000){return base.Int64.min}if(value+1>=0x8000000000000000){return base.Int64.max}if(value<0){return base.Int64.create(-value).negate()}return new base.Int64(value%4294967296|0,value/4294967296)}get isZero(){return this.low===0&&this.high===0}get isNegative(){return this.high<0}negate(){if(this.equals(base.Int64.min)){return base.Int64.min}return this.not().add(base.Int64.one)}not(){return new base.Int64(~this.low,~this.high)}equals(other){if(!(other instanceof base.Int64)&&this.high>>>31===1&&other.high>>>31===1){return false}return this.high===other.high&&this.low===other.low}compare(other){if(this.equals(other)){return 0}const thisNeg=this.isNegative;const otherNeg=other.isNegative;if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}return this.subtract(other).isNegative?-1:1}add(other){return base.Utility.add(this,other,false)}subtract(other){return base.Utility.subtract(this,other,false)}multiply(other){return base.Utility.multiply(this,other,false)}divide(other){return base.Utility.divide(this,other,false)}toInteger(){return this.low}toNumber(){if(this.high===0){return this.low>>>0}if(this.high===-1){return this.low}return this.high*4294967296+(this.low>>>0)}toString(radix){const r=radix||10;if(r<2||r>16){throw new RangeError("radix")}if(this.isZero){return"0"}if(this.high<0){if(this.equals(base.Int64.min)){const radix=new base.Int64(r,0);const div=this.divide(radix);const remainder=div.multiply(radix).subtract(this);return div.toString(radix)+(remainder.low>>>0).toString(radix)}return"-"+this.negate().toString(r)}if(this.high===0){return this.low.toString(radix)}return base.Utility.text(this,false,r)}};base.Int64.min=new base.Int64(0,-2147483648);base.Int64.zero=new base.Int64(0,0);base.Int64.one=new base.Int64(1,0);base.Int64.negativeOne=new base.Int64(-1,0);base.Int64.power24=new base.Int64(1<<24,0);base.Int64.max=new base.Int64(0,2147483647);base.Uint64=class Uint64{constructor(low,high){this.low=low|0;this.high=high|0}static create(value){if(isNaN(value)){return base.Uint64.zero}if(value<0){return base.Uint64.zero}if(value>=0x10000000000000000){return base.Uint64.max}if(value<0){return base.Uint64.create(-value).negate()}return new base.Uint64(value%4294967296|0,value/4294967296)}get isZero(){return this.low===0&&this.high===0}get isNegative(){return false}negate(){return this.not().add(base.Int64.one)}not(){return new base.Uint64(~this.low,~this.high)}equals(other){if(!(other instanceof base.Uint64)&&this.high>>>31===1&&other.high>>>31===1){return false}return this.high===other.high&&this.low===other.low}compare(other){if(this.equals(other)){return 0}const thisNeg=this.isNegative;const otherNeg=other.isNegative;if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}return other.high>>>0>this.high>>>0||other.high===this.high&&other.low>>>0>this.low>>>0?-1:1}add(other){return base.Utility.add(this,other,true)}subtract(other){return base.Utility.subtract(this,other,true)}multiply(other){return base.Utility.multiply(this,other,true)}divide(other){return base.Utility.divide(this,other,true)}toInteger(){return this.low>>>0}toNumber(){if(this.high===0){return this.low>>>0}return(this.high>>>0)*4294967296+(this.low>>>0)}toString(radix){const r=radix||10;if(r<2||36<r){throw new RangeError("radix")}if(this.isZero){return"0"}if(this.high===0){return this.low.toString(radix)}return base.Utility.text(this,true,r)}};base.Utility=class{static add(a,b,unsigned){const a48=a.high>>>16;const a32=a.high&65535;const a16=a.low>>>16;const a00=a.low&65535;const b48=b.high>>>16;const b32=b.high&65535;const b16=b.low>>>16;const b00=b.low&65535;let c48=0;let c32=0;let c16=0;let c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return base.Utility._create(c16<<16|c00,c48<<16|c32,unsigned)}static subtract(a,b,unsigned){return base.Utility.add(a,b.negate(),unsigned)}static multiply(a,b,unsigned){if(a.isZero){return base.Int64.zero}if(b.isZero){return base.Int64.zero}if(a.equals(base.Int64.min)){return b.isOdd()?base.Int64.min:base.Int64.zero}if(b.equals(base.Int64.min)){return a.isOdd()?base.Int64.min:base.Int64.zero}if(a.isNegative){if(b.isNegative){return a.negate().multiply(b.negate())}return a.negate().multiply(b).negate()}else if(b.isNegative){return a.multiply(b.negate()).negate()}if(a.compare(base.Int64.power24)<0&&b.compare(base.Int64.power24)<0){return unsigned?base.Uint64.create(a.toNumber()*b.toNumber()):base.Int64.create(a.toNumber()*b.toNumber())}const a48=a.high>>>16;const a32=a.high&65535;const a16=a.low>>>16;const a00=a.low&65535;const b48=b.high>>>16;const b32=b.high&65535;const b16=b.low>>>16;const b00=b.low&65535;let c48=0;let c32=0;let c16=0;let c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return base.Utility._create(c16<<16|c00,c48<<16|c32,unsigned)}static divide(a,b,unsigned){if(b.isZero){throw new Error("Division by zero.")}if(a.isZero){return unsigned?base.Uint64.zero:base.Int64.zero}let approx;let remainder;let result;if(!unsigned){if(a.equals(base.Int64.min)){if(b.equals(base.Int64.one)||b.equals(base.Int64.negativeOne)){return base.Int64.min}else if(b.equals(base.Int64.min)){return base.Int64.one}const half=base.Utility._shiftRight(a,unsigned,1);const halfDivide=half.divide(b);approx=base.Utility._shiftLeft(halfDivide,halfDivide instanceof base.Uint64,1);if(approx.equals(base.Int64.zero)){return b.isNegative?base.Int64.one:base.Int64.negativeOne}remainder=a.subtract(b.multiply(approx));result=approx.add(remainder.divide(b));return result}else if(b.equals(base.Int64.min)){return base.Int64.zero}if(a.isNegative){if(b.isNegative){return this.negate().divide(b.negate())}return a.negate().divide(b).negate()}else if(b.isNegative){return a.divide(b.negate()).negate()}result=base.Int64.zero}else{if(!(b instanceof base.Uint64)){b=new base.Uint64(b.low,b.high)}if(b.compare(a)>0){return base.Int64.zero}if(b.compare(base.Utility._shiftRight(a,unsigned,1))>0){return base.Uint64.one}result=base.Uint64.zero}remainder=a;while(remainder.compare(b)>=0){let approx=Math.max(1,Math.floor(remainder.toNumber()/b.toNumber()));const log2=Math.ceil(Math.log(approx)/Math.LN2);const delta=log2<=48?1:Math.pow(2,log2-48);let approxResult=base.Int64.create(approx);let approxRemainder=approxResult.multiply(b);while(approxRemainder.isNegative||approxRemainder.compare(remainder)>0){approx-=delta;approxResult=unsigned?base.Uint64.create(approx):base.Int64.create(approx);approxRemainder=approxResult.multiply(b)}if(approxResult.isZero){approxResult=base.Int64.one}result=result.add(approxResult);remainder=remainder.subtract(approxRemainder)}return result}static text(value,unsigned,radix){const power=unsigned?base.Uint64.create(Math.pow(radix,6)):base.Int64.create(Math.pow(radix,6));let remainder=value;let result="";for(;;){const remainderDiv=remainder.divide(power);const intval=remainder.subtract(remainderDiv.multiply(power)).toInteger()>>>0;let digits=intval.toString(radix);remainder=remainderDiv;if(remainder.low===0&&remainder.high===0){return digits+result}while(digits.length<6){digits="0"+digits}result=""+digits+result}}static _shiftLeft(value,unsigned,shift){return base.Utility._create(value.low<<shift,value.high<<shift|value.low>>>32-shift,unsigned)}static _shiftRight(value,unsigned,shift){return base.Utility._create(value.low>>>shift|value.high<<32-shift,value.high>>shift,unsigned)}static _create(low,high,unsigned){return unsigned?new base.Uint64(low,high):new base.Int64(low,high)}};base.Uint64.zero=new base.Uint64(0,0);base.Uint64.one=new base.Uint64(1,0);base.Uint64.max=new base.Uint64(-1,-1);base.Complex64=class Complex{constructor(real,imaginary){this.real=real;this.imaginary=imaginary}static create(real,imaginary){return new base.Complex64(real,imaginary)}toString(){return this.real+" + "+this.imaginary+"i"}};base.Complex128=class Complex{constructor(real,imaginary){this.real=real;this.imaginary=imaginary}static create(real,imaginary){return new base.Complex128(real,imaginary)}toString(){return this.real+" + "+this.imaginary+"i"}};if(!DataView.prototype.getFloat16){DataView.prototype.getFloat16=function(byteOffset,littleEndian){const value=this.getUint16(byteOffset,littleEndian);const e=(value&31744)>>10;let f=value&1023;if(e==0){f=6103515625e-14*(f/1024)}else if(e==31){f=f?NaN:Infinity}else{f=DataView.__float16_pow[e]*(1+f/1024)}return value&32768?-f:f};DataView.__float16_pow={1:1/16384,2:1/8192,3:1/4096,4:1/2048,5:1/1024,6:1/512,7:1/256,8:1/128,9:1/64,10:1/32,11:1/16,12:1/8,13:1/4,14:1/2,15:1,16:2,17:4,18:8,19:16,20:32,21:64,22:128,23:256,24:512,25:1024,26:2048,27:4096,28:8192,29:16384,30:32768,31:65536}}if(!DataView.prototype.setFloat16){DataView.prototype.setFloat16=function(byteOffset,value,littleEndian){DataView.__float16_float[0]=value;[value]=DataView.__float16_int;const s=value>>>16&32768;const e=value>>>23&255;const f=value&8388607;const v=s|DataView.__float16_base[e]|f>>DataView.__float16_shift[e];this.setUint16(byteOffset,v,littleEndian)};DataView.__float16_float=new Float32Array(1);DataView.__float16_int=new Uint32Array(DataView.__float16_float.buffer,0,DataView.__float16_float.length);DataView.__float16_base=new Uint32Array(256);DataView.__float16_shift=new Uint32Array(256);for(let i=0;i<256;++i){const e=i-127;if(e<-27){DataView.__float16_base[i]=0;DataView.__float16_shift[i]=24}else if(e<-14){DataView.__float16_base[i]=1024>>-e-14;DataView.__float16_shift[i]=-e-1}else if(e<=15){DataView.__float16_base[i]=e+15<<10;DataView.__float16_shift[i]=13}else if(e<128){DataView.__float16_base[i]=31744;DataView.__float16_shift[i]=24}else{DataView.__float16_base[i]=31744;DataView.__float16_shift[i]=13}}}if(!DataView.prototype.getBfloat16){DataView.prototype.getBfloat16=function(byteOffset,littleEndian){if(littleEndian){DataView.__bfloat16_get_uint16_le[1]=this.getUint16(byteOffset,littleEndian);return DataView.__bfloat16_get_float32_le[0]}DataView.__bfloat16_uint16_be[0]=this.getUint16(byteOffset,littleEndian);return DataView.__bfloat16_get_float32_be[0]};DataView.__bfloat16_get_float32_le=new Float32Array(1);DataView.__bfloat16_get_float32_be=new Float32Array(1);DataView.__bfloat16_get_uint16_le=new Uint16Array(DataView.__bfloat16_get_float32_le.buffer,DataView.__bfloat16_get_float32_le.byteOffset,2);DataView.__bfloat16_get_uint16_be=new Uint16Array(DataView.__bfloat16_get_float32_be.buffer,DataView.__bfloat16_get_float32_be.byteOffset,2)}DataView.__float8e4m3_float32=new Float32Array(1);DataView.__float8e4m3_uint32=new Uint32Array(DataView.__float8e4m3_float32.buffer,DataView.__float8e4m3_float32.byteOffset,1);DataView.prototype.getFloat8e4m3=function(byteOffset,fn,uz){const value=this.getUint8(byteOffset);let exponent_bias=7;if(uz){exponent_bias=8;if(value==128){return NaN}}else if(value===255){return-NaN}else if(value===127){return NaN}let expo=(value&120)>>3;let mant=value&7;const sign=value&128;let res=sign<<24;if(expo==0){if(mant>0){expo=127-exponent_bias;if(mant&4==0){mant&=3;mant<<=1;expo-=1}if(mant&4==0){mant&=3;mant<<=1;expo-=1}res|=(mant&3)<<21;res|=expo<<23}}else{res|=mant<<20;expo+=127-exponent_bias;res|=expo<<23}DataView.__float8e4m3_uint32[0]=res;return DataView.__float8e4m3_float32[0]};DataView.__float8e5m2_float32=new Float32Array(1);DataView.__float8e5m2_uint32=new Uint32Array(DataView.__float8e5m2_float32.buffer,DataView.__float8e5m2_float32.byteOffset,1);DataView.prototype.getFloat8e5m2=function(byteOffset,fn,uz){const value=this.getUint8(byteOffset);let exponent_bias=NaN;if(fn&&uz){if(value==128){return NaN}exponent_bias=16}else if(!fn&&!uz){if(value>=253&&value<=255){return-NaN}if(value>=126&&value<=127){return NaN}if(value===252){return-Infinity}if(value===124){return Infinity}exponent_bias=15}let expo=(value&124)>>2;let mant=value&3;let res=(value&128)<<24;if(expo==0){if(mant>0){expo=127-exponent_bias;if(mant&2==0){mant&=1;mant<<=1;expo-=1}res|=(mant&1)<<22;res|=expo<<23}}else{res|=mant<<21;expo+=127-exponent_bias;res|=expo<<23}DataView.__float8e5m2_uint32[0]=res;return DataView.__float8e5m2_float32[0]};DataView.prototype.getInt64=DataView.prototype.getInt64||function(byteOffset,littleEndian){return littleEndian?new base.Int64(this.getUint32(byteOffset,true),this.getUint32(byteOffset+4,true)):new base.Int64(this.getUint32(byteOffset+4,true),this.getUint32(byteOffset,true))};DataView.prototype.setInt64=DataView.prototype.setInt64||function(byteOffset,value,littleEndian){if(littleEndian){this.setUint32(byteOffset,value.low,true);this.setUint32(byteOffset+4,value.high,true)}else{this.setUint32(byteOffset+4,value.low,false);this.setUint32(byteOffset,value.high,false)}};DataView.prototype.getIntBits=DataView.prototype.getUintBits||function(offset,bits){offset=offset*bits;const available=(this.byteLength<<3)-offset;if(bits>available){throw new RangeError("Invalid bit size '"+bits+"'.")}let value=0;let index=0;while(index<bits){const remainder=offset&7;const size=Math.min(bits-index,8-remainder);value<<=size;value|=this.getUint8(offset>>3)>>8-size-remainder&~(255<<size);offset+=size;index+=size}return value<2<<bits-1?value:2<<bits};DataView.prototype.getUint64=DataView.prototype.getUint64||function(byteOffset,littleEndian){return littleEndian?new base.Uint64(this.getUint32(byteOffset,true),this.getUint32(byteOffset+4,true)):new base.Uint64(this.getUint32(byteOffset+4,true),this.getUint32(byteOffset,true))};DataView.prototype.setUint64=DataView.prototype.setUint64||function(byteOffset,value,littleEndian){if(littleEndian){this.setUint32(byteOffset,value.low,true);this.setUint32(byteOffset+4,value.high,true)}else{this.setUint32(byteOffset+4,value.low,false);this.setUint32(byteOffset,value.high,false)}};DataView.prototype.getUintBits=DataView.prototype.getUintBits||function(offset,bits){offset=offset*bits;const available=(this.byteLength<<3)-offset;if(bits>available){throw new RangeError("Invalid bit size '"+bits+"'.")}let value=0;let index=0;while(index<bits){const remainder=offset&7;const size=Math.min(bits-index,8-remainder);value<<=size;value|=this.getUint8(offset>>3)>>8-size-remainder&~(255<<size);offset+=size;index+=size}return value};DataView.prototype.getComplex64=DataView.prototype.getComplex64||function(byteOffset,littleEndian){const real=littleEndian?this.getFloat32(byteOffset,littleEndian):this.getFloat32(byteOffset+4,littleEndian);const imaginary=littleEndian?this.getFloat32(byteOffset+4,littleEndian):this.getFloat32(byteOffset,littleEndian);return base.Complex64.create(real,imaginary)};DataView.prototype.setComplex64=DataView.prototype.setComplex64||function(byteOffset,value,littleEndian){if(littleEndian){this.setFloat32(byteOffset,value.real,littleEndian);this.setFloat32(byteOffset+4,value.imaginary,littleEndian)}else{this.setFloat32(byteOffset+4,value.real,littleEndian);this.setFloat32(byteOffset,value.imaginary,littleEndian)}};DataView.prototype.getComplex128=DataView.prototype.getComplex128||function(byteOffset,littleEndian){const real=littleEndian?this.getFloat64(byteOffset,littleEndian):this.getFloat64(byteOffset+8,littleEndian);const imaginary=littleEndian?this.getFloat64(byteOffset+8,littleEndian):this.getFloat64(byteOffset,littleEndian);return base.Complex128.create(real,imaginary)};DataView.prototype.setComplex128=DataView.prototype.setComplex128||function(byteOffset,value,littleEndian){if(littleEndian){this.setFloat64(byteOffset,value.real,littleEndian);this.setFloat64(byteOffset+8,value.imaginary,littleEndian)}else{this.setFloat64(byteOffset+8,value.real,littleEndian);this.setFloat64(byteOffset,value.imaginary,littleEndian)}}; |