code wiki / (root) / nx_gltf_decimal_gate_t181.nx

nx_gltf_decimal_gate_t181.nx source

↩ module page · 55 lines · 4696 B

1import "nx_gltf_accessor_candidate_t181.nx" 2 3// Decimal JSON number to caller-selected fixed precision, toward zero. 4// Error is less than one output unit; overflow refuses instead of saturating. 5func gld_number_fixed(s:*u8,n:i64,q:i64,out:*i64)->i64 { 6 if (s as i64)<=0||(out as i64)<=0||n<=0||n>GLD_I64_MAX-64||q<=0||q>GLD_I64_MAX/10{return -1} 7 var start:i64=0;var sign:i64=1;if s[0]==(45 as u8){start=1;sign=0-1};if start>=n{return -1} 8 var i:i64=start;var digits:i64=0;var before:i64=0;var dot:i64=0;var nonzero:i64=0 9 while i<n&&s[i]!=(101 as u8)&&s[i]!=(69 as u8){ 10 let c:i64=s[i] as i64;if c==46{if dot!=0||digits==0{return -1};dot=1;before=digits}else{if c<48||c>57{return -1};if c!=48{nonzero=1};digits=digits+1};i=i+1 11 } 12 let mend:i64=i;if digits==0||(dot==1&&s[mend-1]==(46 as u8)){return -1};if dot==0{before=digits} 13 if s[start]==(48 as u8)&&before>1{return -1} 14 var ex:i64=0;var es:i64=1;let bound:i64=n+64 15 if i<n{i=i+1;if i<n&&s[i]==(45 as u8){es=0-1;i=i+1}else{if i<n&&s[i]==(43 as u8){i=i+1}};if i>=n{return -1} 16 while i<n{let d:i64=(s[i] as i64)-48;if d<0||d>9{return -1};if ex>(bound-d)/10{ex=bound}else{ex=ex*10+d};i=i+1} 17 } 18 if nonzero==0{out[0]=0;return 0} 19 var point:i64=before;if es>0{if ex>bound-before{point=bound}else{point=before+ex}}else{point=before-ex} 20 let wholemax:i64=GLD_I64_MAX/q;var whole:i64=0;var index:i64=0;i=start 21 while i<mend{let c:i64=s[i] as i64;if c!=46{if index<point{let d:i64=c-48;if whole>(wholemax-d)/10{return -2};whole=whole*10+d};index=index+1};i=i+1} 22 while index<point{if whole>wholemax/10{return -2};whole=whole*10;index=index+1} 23 var fraction:i64=0;index=digits-1;i=mend-1 24 while i>=start{let c:i64=s[i] as i64;if c!=46{if index>=point{fraction=((c-48)*q+fraction)/10};index=index-1};i=i-1} 25 var zeros:i64=0-point;while zeros>0&&fraction>0{fraction=fraction/10;zeros=zeros-1} 26 let base:i64=whole*q;if fraction>GLD_I64_MAX-base{return -2};out[0]=(base+fraction)*sign;return 0 27} 28 29func main()->i64{let out:*i64=sys_mmap(8) as *i64;var bad:i64=0; 30out[0]=991;if gld_number_fixed("0",1,1073741824,out)!=0{bad=bad+1};if out[0]!=0{bad=bad+1} 31out[0]=991;if gld_number_fixed("-0",2,1073741824,out)!=0{bad=bad+1};if out[0]!=0{bad=bad+1} 32out[0]=991;if gld_number_fixed("1",1,1073741824,out)!=0{bad=bad+1};if out[0]!=1073741824{bad=bad+1} 33out[0]=991;if gld_number_fixed("-1",2,1073741824,out)!=0{bad=bad+1};if out[0]!=-1073741824{bad=bad+1} 34out[0]=991;if gld_number_fixed("0.1",3,1073741824,out)!=0{bad=bad+1};if out[0]!=107374182{bad=bad+1} 35out[0]=991;if gld_number_fixed("-0.1",4,1073741824,out)!=0{bad=bad+1};if out[0]!=-107374182{bad=bad+1} 36out[0]=991;if gld_number_fixed("1.999999999999999999999",23,1073741824,out)!=0{bad=bad+1};if out[0]!=2147483647{bad=bad+1} 37out[0]=991;if gld_number_fixed("1e-9",4,1073741824,out)!=0{bad=bad+1};if out[0]!=1{bad=bad+1} 38out[0]=991;if gld_number_fixed("-3.532566552166827e-6",21,1073741824,out)!=0{bad=bad+1};if out[0]!=-3793{bad=bad+1} 39out[0]=991;if gld_number_fixed("136.19120827523045",18,1073741824,out)!=0{bad=bad+1};if out[0]!=146234196386{bad=bad+1} 40out[0]=991;if gld_number_fixed("1.0000001192092896",18,1073741824,out)!=0{bad=bad+1};if out[0]!=1073741952{bad=bad+1} 41out[0]=991;if gld_number_fixed("0.9999999999999999",18,1073741824,out)!=0{bad=bad+1};if out[0]!=1073741823{bad=bad+1} 42out[0]=991;if gld_number_fixed("1e999999",8,1073741824,out)!=-2{bad=bad+1};if out[0]!=991{bad=bad+1} 43out[0]=991;if gld_number_fixed("1e-999999",9,1073741824,out)!=0{bad=bad+1};if out[0]!=0{bad=bad+1} 44out[0]=991;if gld_number_fixed("0e999999",8,1073741824,out)!=0{bad=bad+1};if out[0]!=0{bad=bad+1} 45out[0]=991;if gld_number_fixed("01",2,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 46out[0]=991;if gld_number_fixed("1.",2,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 47out[0]=991;if gld_number_fixed("1e",2,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 48out[0]=991;if gld_number_fixed("+1",2,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 49out[0]=991;if gld_number_fixed("--1",3,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 50out[0]=991;if gld_number_fixed("1..2",4,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 51out[0]=991;if gld_number_fixed("1e+-3",5,1073741824,out)!=-1{bad=bad+1};if out[0]!=991{bad=bad+1} 52out[0]=991;if gld_number_fixed("9223372036854775807",19,1073741824,out)!=-2{bad=bad+1};if out[0]!=991{bad=bad+1} 53out[0]=991;if gld_number_fixed("8589934591.999999999",20,1073741824,out)!=0{bad=bad+1};if out[0]!=9223372036854775806{bad=bad+1} 54out[0]=991;if gld_number_fixed("-8589934591.999999999",21,1073741824,out)!=0{bad=bad+1};if out[0]!=-9223372036854775806{bad=bad+1} 55if bad!=0{return 1};sys_write(1,"DECIMAL_FIXED 25/25\n",19);return 0}