OILS / spec / ysh-int-float.test.sh View on Github | oilshell.org

220 lines, 100 significant
1## oils_failures_allowed: 0
2
3#### Float Literals with e-1
4
5shopt -s ysh:upgrade
6# 1+2 2.3
7var x = 1.2 + 23.0e-1 # 3.5
8if (3.4 < x and x < 3.6) {
9 echo ok
10}
11## STDOUT:
12ok
13## END
14
15#### Float Literal with _
16
17shopt -s ysh:upgrade
18
19# 1+2 + 2.3
20# add this _ here
21var x = 1.2 + 2_3.0e-1 # 3.5
22if (3.4 < x and x < 3.6) {
23 echo ok
24}
25
26## STDOUT:
27ok
28## END
29
30
31#### Period requires digit on either side, not 5. or .5
32echo $[0.5]
33echo $[5.0]
34echo $[5.]
35echo $[.5]
36
37## status: 2
38## STDOUT:
390.5
405.0
41## END
42
43#### Big float Literals with _
44
45# C++ issue: we currently print with snprintf %g
46# Pars
47
48echo $[42_000.000_500]
49
50echo $[42_000.000_500e1]
51echo $[42_000.000_500e-1]
52
53## STDOUT:
5442000.0005
55420000.005
564200.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
65echo $[1e309]
66echo $[-1e309]
67
68## STDOUT:
69inf
70-inf
71## END
72
73#### Tiny floats go to zero
74
75shopt -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
82var zeros = []
83for i in (1 .. 324) {
84 call zeros->append('0')
85}
86
87#= zeros
88
89var s = "0.$[join(zeros)]1"
90#echo $s
91
92echo float=$[float(s)]
93
94## STDOUT:
95float=0.0
96## END
97
98
99#### floatEquals() INFINITY NAN
100
101shopt --set ysh:upgrade
102source $LIB_YSH/list.ysh
103
104# Create inf
105var big = repeat('12345678', 100) ++ '.0'
106
107var inf = fromJson(big)
108var neg_inf = fromJson('-' ++ big)
109
110if (floatsEqual(inf, INFINITY)) {
111 echo inf
112}
113
114if (floatsEqual(neg_inf, -INFINITY)) {
115 echo neg_inf
116}
117
118if (floatsEqual(NAN, INFINITY)) {
119 echo bad
120}
121
122if (floatsEqual(NAN, NAN)) {
123 echo bad
124}
125
126if (not floatsEqual(NAN, NAN)) {
127 echo 'nan is not nan'
128}
129
130## STDOUT:
131inf
132neg_inf
133nan is not nan
134## END
135
136#### pretty print INFINITY, -INFINITY, NAN
137
138= [INFINITY, -INFINITY, NAN]
139pp test_ ([INFINITY, -INFINITY, NAN])
140
141## STDOUT:
142(List) [INFINITY, -INFINITY, NAN]
143(List) [INFINITY,-INFINITY,NAN]
144## END
145
146#### can't convert NAN, INFINITY to integer
147shopt --set ysh:upgrade
148
149#echo $[int(NAN)]
150try {
151 echo $[int(NAN)]
152}
153echo code $[_error.code]
154#pp test_ (_error)
155
156#echo $[int(-INFINITY)]
157try {
158 echo $[int(-INFINITY)]
159}
160echo code $[_error.code]
161#pp test_ (_error)
162
163## STDOUT:
164code 3
165code 3
166## END
167
168#### Regression: 1/3 gives 0.3+
169
170# We were using float precision, not double
171
172shopt --set ysh:upgrade
173
174pp test_ (1/3) | read --all
175if (_reply ~ / '0.' '3'+ / ) {
176 echo one-third
177}
178
179pp test_ (2/3) | read --all
180#pp test_ (_reply)
181if (_reply ~ / '0.' '6'+ / ) {
182 echo two-thirds
183}
184
185## STDOUT:
186one-third
187two-thirds
188## END
189
190#### Number of digits in 1/3
191shopt --set ysh:upgrade
192
193# - Python 2 and bin/ysh: 14
194# - Python 3: 18
195# - YSH C++: 18
196
197var s = str(1/3)
198#echo "ysh len $[len(s)]"
199#echo ysh=$s
200
201# Don't bother to distinguish OSH Python vs C++ here
202case (len(s)) {
203 (14) { echo pass }
204 (18) { echo pass }
205 (else) { echo FAIL }
206}
207
208exit
209
210var py2 = $(python2 -c 'print(1.0/3)')
211echo "py2 len $[len(py2)]"
212echo py2=$py2
213
214var py3 = $(python3 -c 'print(1/3)')
215echo "py3 len $[len(py3)]"
216echo py3=$py3
217
218## STDOUT:
219pass
220## END