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}