1 ## oils_failures_allowed: 0
2
3 #### Float Literals with e-1
4
5 shopt -s ysh:upgrade
6 # 1+2 2.3
7 var x = 1.2 + 23.0e-1 # 3.5
8 if (3.4 < x and x < 3.6) {
9 echo ok
10 }
11 ## STDOUT:
12 ok
13 ## END
14
15 #### Float Literal with _
16
17 shopt -s ysh:upgrade
18
19 # 1+2 + 2.3
20 # add this _ here
21 var x = 1.2 + 2_3.0e-1 # 3.5
22 if (3.4 < x and x < 3.6) {
23 echo ok
24 }
25
26 ## STDOUT:
27 ok
28 ## END
29
30
31 #### Period requires digit on either side, not 5. or .5
32 echo $[0.5]
33 echo $[5.0]
34 echo $[5.]
35 echo $[.5]
36
37 ## status: 2
38 ## STDOUT:
39 0.5
40 5.0
41 ## END
42
43 #### Big float Literals with _
44
45 # C++ issue: we currently print with snprintf %g
46 # Pars
47
48 echo $[42_000.000_500]
49
50 echo $[42_000.000_500e1]
51 echo $[42_000.000_500e-1]
52
53 ## STDOUT:
54 42000.0005
55 420000.005
56 4200.00005
57 ## END
58
59 #### Big floats like 1e309 and -1e309 go to Inf / -Inf
60
61 # Notes
62 # - Python float() and JS parseFloat() agree with this behavior
63 # - JSON doesn't have inf / -inf
64
65 echo $[1e309]
66 echo $[-1e309]
67
68 ## STDOUT:
69 inf
70 -inf
71 ## END
72
73 #### Tiny floats go to zero
74
75 shopt -s ysh:upgrade
76 # TODO: need equivalent of in YSh
77 # '0' * 309
78 # ['0'] * 309
79
80 # 1e-324 == 0.0 in Python
81
82 var zeros = []
83 for i in (1 .. 324) {
84 call zeros->append('0')
85 }
86
87 #= zeros
88
89 var s = "0.$[join(zeros)]1"
90 #echo $s
91
92 echo float=$[float(s)]
93
94 ## STDOUT:
95 float=0.0
96 ## END
97
98
99 #### floatEquals() INFINITY NAN
100
101 shopt --set ysh:upgrade
102 source $LIB_YSH/list.ysh
103
104 # Create inf
105 var big = repeat('12345678', 100) ++ '.0'
106
107 var inf = fromJson(big)
108 var neg_inf = fromJson('-' ++ big)
109
110 if (floatsEqual(inf, INFINITY)) {
111 echo inf
112 }
113
114 if (floatsEqual(neg_inf, -INFINITY)) {
115 echo neg_inf
116 }
117
118 if (floatsEqual(NAN, INFINITY)) {
119 echo bad
120 }
121
122 if (floatsEqual(NAN, NAN)) {
123 echo bad
124 }
125
126 if (not floatsEqual(NAN, NAN)) {
127 echo 'nan is not nan'
128 }
129
130 ## STDOUT:
131 inf
132 neg_inf
133 nan is not nan
134 ## END
135
136 #### Regression: 1/3 gives 0.3+
137
138 # We were using float precision, not double
139
140 shopt --set ysh:upgrade
141
142 pp line (1/3) | read --all
143 if (_reply ~ / '0.' '3'+ / ) {
144 echo one-third
145 }
146
147 pp line (2/3) | read --all
148 if (_reply ~ / '0.' '6'+ '7' / ) {
149 echo two-thirds
150 }
151
152 ## STDOUT:
153 one-third
154 two-thirds
155 ## END
156
157 #### Number of digits in 1/3
158 shopt --set ysh:upgrade
159
160 # - Python 2 and bin/ysh: 14
161 # - Python 3: 18
162 # - YSH C++: 19 - see mycpp/float_test.cc, tip from Bruce Dawson
163
164 var s = str(1/3)
165 #echo "ysh len $[len(s)]"
166 #echo ysh=$s
167
168 # Don't bother to distinguish OSH Python vs C++ here
169 case (len(s)) {
170 (14) { echo pass }
171 (19) { echo pass }
172 (else) { echo FAIL }
173 }
174
175 exit
176
177 var py2 = $(python2 -c 'print(1.0/3)')
178 echo "py2 len $[len(py2)]"
179 echo py2=$py2
180
181 var py3 = $(python3 -c 'print(1/3)')
182 echo "py3 len $[len(py3)]"
183 echo py3=$py3
184
185 ## STDOUT:
186 pass
187 ## END