1*4947cdc7SCole Faust# Tests of Starlark 'float' 2*4947cdc7SCole Faust# option:set 3*4947cdc7SCole Faust 4*4947cdc7SCole Faustload("assert.star", "assert") 5*4947cdc7SCole Faust 6*4947cdc7SCole Faust# TODO(adonovan): more tests: 7*4947cdc7SCole Faust# - precision 8*4947cdc7SCole Faust# - limits 9*4947cdc7SCole Faust 10*4947cdc7SCole Faust# type 11*4947cdc7SCole Faustassert.eq(type(0.0), "float") 12*4947cdc7SCole Faust 13*4947cdc7SCole Faust# truth 14*4947cdc7SCole Faustassert.true(123.0) 15*4947cdc7SCole Faustassert.true(-1.0) 16*4947cdc7SCole Faustassert.true(not 0.0) 17*4947cdc7SCole Faustassert.true(-1.0e-45) 18*4947cdc7SCole Faustassert.true(float("NaN")) 19*4947cdc7SCole Faust 20*4947cdc7SCole Faust# not iterable 21*4947cdc7SCole Faustassert.fails(lambda: len(0.0), 'has no len') 22*4947cdc7SCole Faustassert.fails(lambda: [x for x in 0.0], 'float value is not iterable') 23*4947cdc7SCole Faust 24*4947cdc7SCole Faust# literals 25*4947cdc7SCole Faustassert.eq(type(1.234), "float") 26*4947cdc7SCole Faustassert.eq(type(1e10), "float") 27*4947cdc7SCole Faustassert.eq(type(1e+10), "float") 28*4947cdc7SCole Faustassert.eq(type(1e-10), "float") 29*4947cdc7SCole Faustassert.eq(type(1.234e10), "float") 30*4947cdc7SCole Faustassert.eq(type(1.234e+10), "float") 31*4947cdc7SCole Faustassert.eq(type(1.234e-10), "float") 32*4947cdc7SCole Faust 33*4947cdc7SCole Faust# int/float equality 34*4947cdc7SCole Faustassert.eq(0.0, 0) 35*4947cdc7SCole Faustassert.eq(0, 0.0) 36*4947cdc7SCole Faustassert.eq(1.0, 1) 37*4947cdc7SCole Faustassert.eq(1, 1.0) 38*4947cdc7SCole Faustassert.true(1.23e45 != 1229999999999999973814869011019624571608236031) 39*4947cdc7SCole Faustassert.true(1.23e45 == 1229999999999999973814869011019624571608236032) 40*4947cdc7SCole Faustassert.true(1.23e45 != 1229999999999999973814869011019624571608236033) 41*4947cdc7SCole Faustassert.true(1229999999999999973814869011019624571608236031 != 1.23e45) 42*4947cdc7SCole Faustassert.true(1229999999999999973814869011019624571608236032 == 1.23e45) 43*4947cdc7SCole Faustassert.true(1229999999999999973814869011019624571608236033 != 1.23e45) 44*4947cdc7SCole Faust 45*4947cdc7SCole Faust# loss of precision 46*4947cdc7SCole Faustp53 = 1<<53 47*4947cdc7SCole Faustassert.eq(float(p53-1), p53-1) 48*4947cdc7SCole Faustassert.eq(float(p53+0), p53+0) 49*4947cdc7SCole Faustassert.eq(float(p53+1), p53+0) # 50*4947cdc7SCole Faustassert.eq(float(p53+2), p53+2) 51*4947cdc7SCole Faustassert.eq(float(p53+3), p53+4) # 52*4947cdc7SCole Faustassert.eq(float(p53+4), p53+4) 53*4947cdc7SCole Faustassert.eq(float(p53+5), p53+4) # 54*4947cdc7SCole Faustassert.eq(float(p53+6), p53+6) 55*4947cdc7SCole Faustassert.eq(float(p53+7), p53+8) # 56*4947cdc7SCole Faustassert.eq(float(p53+8), p53+8) 57*4947cdc7SCole Faust 58*4947cdc7SCole Faustassert.true(float(p53+1) != p53+1) # comparisons are exact 59*4947cdc7SCole Faustassert.eq(float(p53+1) - (p53+1), 0) # arithmetic entails rounding 60*4947cdc7SCole Faust 61*4947cdc7SCole Faustassert.fails(lambda: {123.0: "f", 123: "i"}, "duplicate key: 123") 62*4947cdc7SCole Faust 63*4947cdc7SCole Faust# equal int/float values have same hash 64*4947cdc7SCole Faustd = {123.0: "x"} 65*4947cdc7SCole Faustd[123] = "y" 66*4947cdc7SCole Faustassert.eq(len(d), 1) 67*4947cdc7SCole Faustassert.eq(d[123.0], "y") 68*4947cdc7SCole Faust 69*4947cdc7SCole Faust# literals (mostly covered by scanner tests) 70*4947cdc7SCole Faustassert.eq(str(0.), "0.0") 71*4947cdc7SCole Faustassert.eq(str(.0), "0.0") 72*4947cdc7SCole Faustassert.true(5.0 != 4.999999999999999) 73*4947cdc7SCole Faustassert.eq(5.0, 4.9999999999999999) # both literals denote 5.0 74*4947cdc7SCole Faustassert.eq(1.23e45, 1.23 * 1000000000000000000000000000000000000000000000) 75*4947cdc7SCole Faustassert.eq(str(1.23e-45 - (1.23 / 1000000000000000000000000000000000000000000000)), "-1.5557538194652854e-61") 76*4947cdc7SCole Faust 77*4947cdc7SCole Faustnan = float("NaN") 78*4947cdc7SCole Faustinf = float("+Inf") 79*4947cdc7SCole Faustneginf = float("-Inf") 80*4947cdc7SCole Faustnegzero = (-1e-323 / 10) 81*4947cdc7SCole Faust 82*4947cdc7SCole Faust# -- arithmetic -- 83*4947cdc7SCole Faust 84*4947cdc7SCole Faust# +float, -float 85*4947cdc7SCole Faustassert.eq(+(123.0), 123.0) 86*4947cdc7SCole Faustassert.eq(-(123.0), -123.0) 87*4947cdc7SCole Faustassert.eq(-(-(123.0)), 123.0) 88*4947cdc7SCole Faustassert.eq(+(inf), inf) 89*4947cdc7SCole Faustassert.eq(-(inf), neginf) 90*4947cdc7SCole Faustassert.eq(-(neginf), inf) 91*4947cdc7SCole Faustassert.eq(str(-(nan)), "nan") 92*4947cdc7SCole Faust# + 93*4947cdc7SCole Faustassert.eq(1.2e3 + 5.6e7, 5.60012e+07) 94*4947cdc7SCole Faustassert.eq(1.2e3 + 1, 1201) 95*4947cdc7SCole Faustassert.eq(1 + 1.2e3, 1201) 96*4947cdc7SCole Faustassert.eq(str(1.2e3 + nan), "nan") 97*4947cdc7SCole Faustassert.eq(inf + 0, inf) 98*4947cdc7SCole Faustassert.eq(inf + 1, inf) 99*4947cdc7SCole Faustassert.eq(inf + inf, inf) 100*4947cdc7SCole Faustassert.eq(str(inf + neginf), "nan") 101*4947cdc7SCole Faust# - 102*4947cdc7SCole Faustassert.eq(1.2e3 - 5.6e7, -5.59988e+07) 103*4947cdc7SCole Faustassert.eq(1.2e3 - 1, 1199) 104*4947cdc7SCole Faustassert.eq(1 - 1.2e3, -1199) 105*4947cdc7SCole Faustassert.eq(str(1.2e3 - nan), "nan") 106*4947cdc7SCole Faustassert.eq(inf - 0, inf) 107*4947cdc7SCole Faustassert.eq(inf - 1, inf) 108*4947cdc7SCole Faustassert.eq(str(inf - inf), "nan") 109*4947cdc7SCole Faustassert.eq(inf - neginf, inf) 110*4947cdc7SCole Faust# * 111*4947cdc7SCole Faustassert.eq(1.5e6 * 2.2e3, 3.3e9) 112*4947cdc7SCole Faustassert.eq(1.5e6 * 123, 1.845e+08) 113*4947cdc7SCole Faustassert.eq(123 * 1.5e6, 1.845e+08) 114*4947cdc7SCole Faustassert.eq(str(1.2e3 * nan), "nan") 115*4947cdc7SCole Faustassert.eq(str(inf * 0), "nan") 116*4947cdc7SCole Faustassert.eq(inf * 1, inf) 117*4947cdc7SCole Faustassert.eq(inf * inf, inf) 118*4947cdc7SCole Faustassert.eq(inf * neginf, neginf) 119*4947cdc7SCole Faust# % 120*4947cdc7SCole Faustassert.eq(100.0 % 7.0, 2) 121*4947cdc7SCole Faustassert.eq(100.0 % -7.0, -5) # NB: different from Go / Java 122*4947cdc7SCole Faustassert.eq(-100.0 % 7.0, 5) # NB: different from Go / Java 123*4947cdc7SCole Faustassert.eq(-100.0 % -7.0, -2) 124*4947cdc7SCole Faustassert.eq(-100.0 % 7, 5) 125*4947cdc7SCole Faustassert.eq(100 % 7.0, 2) 126*4947cdc7SCole Faustassert.eq(str(1.2e3 % nan), "nan") 127*4947cdc7SCole Faustassert.eq(str(inf % 1), "nan") 128*4947cdc7SCole Faustassert.eq(str(inf % inf), "nan") 129*4947cdc7SCole Faustassert.eq(str(inf % neginf), "nan") 130*4947cdc7SCole Faust# / 131*4947cdc7SCole Faustassert.eq(str(100.0 / 7.0), "14.285714285714286") 132*4947cdc7SCole Faustassert.eq(str(100 / 7.0), "14.285714285714286") 133*4947cdc7SCole Faustassert.eq(str(100.0 / 7), "14.285714285714286") 134*4947cdc7SCole Faustassert.eq(str(100.0 / nan), "nan") 135*4947cdc7SCole Faust# // 136*4947cdc7SCole Faustassert.eq(100.0 // 7.0, 14) 137*4947cdc7SCole Faustassert.eq(100 // 7.0, 14) 138*4947cdc7SCole Faustassert.eq(100.0 // 7, 14) 139*4947cdc7SCole Faustassert.eq(100.0 // -7.0, -15) 140*4947cdc7SCole Faustassert.eq(100 // -7.0, -15) 141*4947cdc7SCole Faustassert.eq(100.0 // -7, -15) 142*4947cdc7SCole Faustassert.eq(str(1 // neginf), "-0.0") 143*4947cdc7SCole Faustassert.eq(str(100.0 // nan), "nan") 144*4947cdc7SCole Faust 145*4947cdc7SCole Faust# addition 146*4947cdc7SCole Faustassert.eq(0.0 + 1.0, 1.0) 147*4947cdc7SCole Faustassert.eq(1.0 + 1.0, 2.0) 148*4947cdc7SCole Faustassert.eq(1.25 + 2.75, 4.0) 149*4947cdc7SCole Faustassert.eq(5.0 + 7.0, 12.0) 150*4947cdc7SCole Faustassert.eq(5.1 + 7, 12.1) # float + int 151*4947cdc7SCole Faustassert.eq(7 + 5.1, 12.1) # int + float 152*4947cdc7SCole Faust 153*4947cdc7SCole Faust# subtraction 154*4947cdc7SCole Faustassert.eq(5.0 - 7.0, -2.0) 155*4947cdc7SCole Faustassert.eq(5.1 - 7.1, -2.0) 156*4947cdc7SCole Faustassert.eq(5.5 - 7, -1.5) 157*4947cdc7SCole Faustassert.eq(5 - 7.5, -2.5) 158*4947cdc7SCole Faustassert.eq(0.0 - 1.0, -1.0) 159*4947cdc7SCole Faust 160*4947cdc7SCole Faust# multiplication 161*4947cdc7SCole Faustassert.eq(5.0 * 7.0, 35.0) 162*4947cdc7SCole Faustassert.eq(5.5 * 2.5, 13.75) 163*4947cdc7SCole Faustassert.eq(5.5 * 7, 38.5) 164*4947cdc7SCole Faustassert.eq(5 * 7.1, 35.5) 165*4947cdc7SCole Faust 166*4947cdc7SCole Faust# real division (like Python 3) 167*4947cdc7SCole Faust# The / operator is available only when the 'fp' dialect option is enabled. 168*4947cdc7SCole Faustassert.eq(100.0 / 8.0, 12.5) 169*4947cdc7SCole Faustassert.eq(100.0 / -8.0, -12.5) 170*4947cdc7SCole Faustassert.eq(-100.0 / 8.0, -12.5) 171*4947cdc7SCole Faustassert.eq(-100.0 / -8.0, 12.5) 172*4947cdc7SCole Faustassert.eq(98.0 / 8.0, 12.25) 173*4947cdc7SCole Faustassert.eq(98.0 / -8.0, -12.25) 174*4947cdc7SCole Faustassert.eq(-98.0 / 8.0, -12.25) 175*4947cdc7SCole Faustassert.eq(-98.0 / -8.0, 12.25) 176*4947cdc7SCole Faustassert.eq(2.5 / 2.0, 1.25) 177*4947cdc7SCole Faustassert.eq(2.5 / 2, 1.25) 178*4947cdc7SCole Faustassert.eq(5 / 4.0, 1.25) 179*4947cdc7SCole Faustassert.eq(5 / 4, 1.25) 180*4947cdc7SCole Faustassert.fails(lambda: 1.0 / 0, "floating-point division by zero") 181*4947cdc7SCole Faustassert.fails(lambda: 1.0 / 0.0, "floating-point division by zero") 182*4947cdc7SCole Faustassert.fails(lambda: 1 / 0.0, "floating-point division by zero") 183*4947cdc7SCole Faust 184*4947cdc7SCole Faust# floored division 185*4947cdc7SCole Faustassert.eq(100.0 // 8.0, 12.0) 186*4947cdc7SCole Faustassert.eq(100.0 // -8.0, -13.0) 187*4947cdc7SCole Faustassert.eq(-100.0 // 8.0, -13.0) 188*4947cdc7SCole Faustassert.eq(-100.0 // -8.0, 12.0) 189*4947cdc7SCole Faustassert.eq(98.0 // 8.0, 12.0) 190*4947cdc7SCole Faustassert.eq(98.0 // -8.0, -13.0) 191*4947cdc7SCole Faustassert.eq(-98.0 // 8.0, -13.0) 192*4947cdc7SCole Faustassert.eq(-98.0 // -8.0, 12.0) 193*4947cdc7SCole Faustassert.eq(2.5 // 2.0, 1.0) 194*4947cdc7SCole Faustassert.eq(2.5 // 2, 1.0) 195*4947cdc7SCole Faustassert.eq(5 // 4.0, 1.0) 196*4947cdc7SCole Faustassert.eq(5 // 4, 1) 197*4947cdc7SCole Faustassert.eq(type(5 // 4), "int") 198*4947cdc7SCole Faustassert.fails(lambda: 1.0 // 0, "floored division by zero") 199*4947cdc7SCole Faustassert.fails(lambda: 1.0 // 0.0, "floored division by zero") 200*4947cdc7SCole Faustassert.fails(lambda: 1 // 0.0, "floored division by zero") 201*4947cdc7SCole Faust 202*4947cdc7SCole Faust# remainder 203*4947cdc7SCole Faustassert.eq(100.0 % 8.0, 4.0) 204*4947cdc7SCole Faustassert.eq(100.0 % -8.0, -4.0) 205*4947cdc7SCole Faustassert.eq(-100.0 % 8.0, 4.0) 206*4947cdc7SCole Faustassert.eq(-100.0 % -8.0, -4.0) 207*4947cdc7SCole Faustassert.eq(98.0 % 8.0, 2.0) 208*4947cdc7SCole Faustassert.eq(98.0 % -8.0, -6.0) 209*4947cdc7SCole Faustassert.eq(-98.0 % 8.0, 6.0) 210*4947cdc7SCole Faustassert.eq(-98.0 % -8.0, -2.0) 211*4947cdc7SCole Faustassert.eq(2.5 % 2.0, 0.5) 212*4947cdc7SCole Faustassert.eq(2.5 % 2, 0.5) 213*4947cdc7SCole Faustassert.eq(5 % 4.0, 1.0) 214*4947cdc7SCole Faustassert.fails(lambda: 1.0 % 0, "floating-point modulo by zero") 215*4947cdc7SCole Faustassert.fails(lambda: 1.0 % 0.0, "floating-point modulo by zero") 216*4947cdc7SCole Faustassert.fails(lambda: 1 % 0.0, "floating-point modulo by zero") 217*4947cdc7SCole Faust 218*4947cdc7SCole Faust# floats cannot be used as indices, even if integral 219*4947cdc7SCole Faustassert.fails(lambda: "abc"[1.0], "want int") 220*4947cdc7SCole Faustassert.fails(lambda: ["A", "B", "C"].insert(1.0, "D"), "want int") 221*4947cdc7SCole Faustassert.fails(lambda: range(3)[1.0], "got float, want int") 222*4947cdc7SCole Faust 223*4947cdc7SCole Faust# -- comparisons -- 224*4947cdc7SCole Faust# NaN 225*4947cdc7SCole Faustassert.true(nan == nan) # \ 226*4947cdc7SCole Faustassert.true(nan >= nan) # unlike Python 227*4947cdc7SCole Faustassert.true(nan <= nan) # / 228*4947cdc7SCole Faustassert.true(not (nan > nan)) 229*4947cdc7SCole Faustassert.true(not (nan < nan)) 230*4947cdc7SCole Faustassert.true(not (nan != nan)) # unlike Python 231*4947cdc7SCole Faust# Sort is stable: 0.0 and -0.0 are equal, but they are not permuted. 232*4947cdc7SCole Faust# Similarly 1 and 1.0. 233*4947cdc7SCole Faustassert.eq( 234*4947cdc7SCole Faust str(sorted([inf, neginf, nan, 1e300, -1e300, 1.0, -1.0, 1, -1, 1e-300, -1e-300, 0, 0.0, negzero, 1e-300, -1e-300])), 235*4947cdc7SCole Faust "[-inf, -1e+300, -1.0, -1, -1e-300, -1e-300, 0, 0.0, -0.0, 1e-300, 1e-300, 1.0, 1, 1e+300, +inf, nan]") 236*4947cdc7SCole Faust 237*4947cdc7SCole Faust# Sort is stable, and its result contains no adjacent x, y such that y > x. 238*4947cdc7SCole Faust# Note: Python's reverse sort is unstable; see https://bugs.python.org/issue36095. 239*4947cdc7SCole Faustassert.eq(str(sorted([7, 3, nan, 1, 9])), "[1, 3, 7, 9, nan]") 240*4947cdc7SCole Faustassert.eq(str(sorted([7, 3, nan, 1, 9], reverse=True)), "[nan, 9, 7, 3, 1]") 241*4947cdc7SCole Faust 242*4947cdc7SCole Faust# All NaN values compare equal. (Identical objects compare equal.) 243*4947cdc7SCole Faustnandict = {nan: 1} 244*4947cdc7SCole Faustnandict[nan] = 2 245*4947cdc7SCole Faustassert.eq(len(nandict), 1) # (same as Python) 246*4947cdc7SCole Faustassert.eq(nandict[nan], 2) # (same as Python) 247*4947cdc7SCole Faustassert.fails(lambda: {nan: 1, nan: 2}, "duplicate key: nan") 248*4947cdc7SCole Faust 249*4947cdc7SCole Faustnandict[float('nan')] = 3 # a distinct NaN object 250*4947cdc7SCole Faustassert.eq(str(nandict), "{nan: 3}") # (Python: {nan: 2, nan: 3}) 251*4947cdc7SCole Faust 252*4947cdc7SCole Faustassert.eq(str({inf: 1, neginf: 2}), "{+inf: 1, -inf: 2}") 253*4947cdc7SCole Faust 254*4947cdc7SCole Faust# zero 255*4947cdc7SCole Faustassert.eq(0.0, negzero) 256*4947cdc7SCole Faust 257*4947cdc7SCole Faust# inf 258*4947cdc7SCole Faustassert.eq(+inf / +inf, nan) 259*4947cdc7SCole Faustassert.eq(+inf / -inf, nan) 260*4947cdc7SCole Faustassert.eq(-inf / +inf, nan) 261*4947cdc7SCole Faustassert.eq(0.0 / +inf, 0.0) 262*4947cdc7SCole Faustassert.eq(0.0 / -inf, 0.0) 263*4947cdc7SCole Faustassert.true(inf > -inf) 264*4947cdc7SCole Faustassert.eq(inf, -neginf) 265*4947cdc7SCole Faust# TODO(adonovan): assert inf > any finite number, etc. 266*4947cdc7SCole Faust 267*4947cdc7SCole Faust# negative zero 268*4947cdc7SCole Faustnegz = -0 269*4947cdc7SCole Faustassert.eq(negz, 0) 270*4947cdc7SCole Faust 271*4947cdc7SCole Faust# min/max ordering with NaN (the greatest float value) 272*4947cdc7SCole Faustassert.eq(max([1, nan, 3]), nan) 273*4947cdc7SCole Faustassert.eq(max([nan, 2, 3]), nan) 274*4947cdc7SCole Faustassert.eq(min([1, nan, 3]), 1) 275*4947cdc7SCole Faustassert.eq(min([nan, 2, 3]), 2) 276*4947cdc7SCole Faust 277*4947cdc7SCole Faust# float/float comparisons 278*4947cdc7SCole Faustfltmax = 1.7976931348623157e+308 # approx 279*4947cdc7SCole Faustfltmin = 4.9406564584124654e-324 # approx 280*4947cdc7SCole Faustassert.lt(-inf, -fltmax) 281*4947cdc7SCole Faustassert.lt(-fltmax, -1.0) 282*4947cdc7SCole Faustassert.lt(-1.0, -fltmin) 283*4947cdc7SCole Faustassert.lt(-fltmin, 0.0) 284*4947cdc7SCole Faustassert.lt(0, fltmin) 285*4947cdc7SCole Faustassert.lt(fltmin, 1.0) 286*4947cdc7SCole Faustassert.lt(1.0, fltmax) 287*4947cdc7SCole Faustassert.lt(fltmax, inf) 288*4947cdc7SCole Faust 289*4947cdc7SCole Faust# int/float comparisons 290*4947cdc7SCole Faustassert.eq(0, 0.0) 291*4947cdc7SCole Faustassert.eq(1, 1.0) 292*4947cdc7SCole Faustassert.eq(-1, -1.0) 293*4947cdc7SCole Faustassert.ne(-1, -1.0 + 1e-7) 294*4947cdc7SCole Faustassert.lt(-2, -2 + 1e-15) 295*4947cdc7SCole Faust 296*4947cdc7SCole Faust# int conversion (rounds towards zero) 297*4947cdc7SCole Faustassert.eq(int(100.1), 100) 298*4947cdc7SCole Faustassert.eq(int(100.0), 100) 299*4947cdc7SCole Faustassert.eq(int(99.9), 99) 300*4947cdc7SCole Faustassert.eq(int(-99.9), -99) 301*4947cdc7SCole Faustassert.eq(int(-100.0), -100) 302*4947cdc7SCole Faustassert.eq(int(-100.1), -100) 303*4947cdc7SCole Faustassert.eq(int(1e100), int("10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104")) 304*4947cdc7SCole Faustassert.fails(lambda: int(inf), "cannot convert.*infinity") 305*4947cdc7SCole Faustassert.fails(lambda: int(nan), "cannot convert.*NaN") 306*4947cdc7SCole Faust 307*4947cdc7SCole Faust# -- float() function -- 308*4947cdc7SCole Faustassert.eq(float(), 0.0) 309*4947cdc7SCole Faust# float(bool) 310*4947cdc7SCole Faustassert.eq(float(False), 0.0) 311*4947cdc7SCole Faustassert.eq(float(True), 1.0) 312*4947cdc7SCole Faust# float(int) 313*4947cdc7SCole Faustassert.eq(float(0), 0.0) 314*4947cdc7SCole Faustassert.eq(float(1), 1.0) 315*4947cdc7SCole Faustassert.eq(float(123), 123.0) 316*4947cdc7SCole Faustassert.eq(float(123 * 1000000 * 1000000 * 1000000 * 1000000 * 1000000), 1.23e+32) 317*4947cdc7SCole Faust# float(float) 318*4947cdc7SCole Faustassert.eq(float(1.1), 1.1) 319*4947cdc7SCole Faustassert.fails(lambda: float(None), "want number or string") 320*4947cdc7SCole Faustassert.ne(False, 0.0) # differs from Python 321*4947cdc7SCole Faustassert.ne(True, 1.0) 322*4947cdc7SCole Faust# float(string) 323*4947cdc7SCole Faustassert.eq(float("1.1"), 1.1) 324*4947cdc7SCole Faustassert.fails(lambda: float("1.1abc"), "invalid float literal") 325*4947cdc7SCole Faustassert.fails(lambda: float("1e100.0"), "invalid float literal") 326*4947cdc7SCole Faustassert.fails(lambda: float("1e1000"), "floating-point number too large") 327*4947cdc7SCole Faustassert.eq(float("-1.1"), -1.1) 328*4947cdc7SCole Faustassert.eq(float("+1.1"), +1.1) 329*4947cdc7SCole Faustassert.eq(float("+Inf"), inf) 330*4947cdc7SCole Faustassert.eq(float("-Inf"), neginf) 331*4947cdc7SCole Faustassert.eq(float("NaN"), nan) 332*4947cdc7SCole Faustassert.eq(float("NaN"), nan) 333*4947cdc7SCole Faustassert.eq(float("+NAN"), nan) 334*4947cdc7SCole Faustassert.eq(float("-nan"), nan) 335*4947cdc7SCole Faustassert.eq(str(float("Inf")), "+inf") 336*4947cdc7SCole Faustassert.eq(str(float("+INF")), "+inf") 337*4947cdc7SCole Faustassert.eq(str(float("-inf")), "-inf") 338*4947cdc7SCole Faustassert.eq(str(float("+InFiniTy")), "+inf") 339*4947cdc7SCole Faustassert.eq(str(float("-iNFiniTy")), "-inf") 340*4947cdc7SCole Faustassert.fails(lambda: float("one point two"), "invalid float literal: one point two") 341*4947cdc7SCole Faustassert.fails(lambda: float("1.2.3"), "invalid float literal: 1.2.3") 342*4947cdc7SCole Faustassert.fails(lambda: float(123 << 500 << 500 << 50), "int too large to convert to float") 343*4947cdc7SCole Faustassert.fails(lambda: float(-123 << 500 << 500 << 50), "int too large to convert to float") 344*4947cdc7SCole Faustassert.fails(lambda: float(str(-123 << 500 << 500 << 50)), "floating-point number too large") 345*4947cdc7SCole Faust 346*4947cdc7SCole Faust# -- implicit float(int) conversions -- 347*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) + 0.0, "int too large to convert to float") 348*4947cdc7SCole Faustassert.fails(lambda: 0.0 + (1<<500<<500<<500), "int too large to convert to float") 349*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) - 0.0, "int too large to convert to float") 350*4947cdc7SCole Faustassert.fails(lambda: 0.0 - (1<<500<<500<<500), "int too large to convert to float") 351*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) * 1.0, "int too large to convert to float") 352*4947cdc7SCole Faustassert.fails(lambda: 1.0 * (1<<500<<500<<500), "int too large to convert to float") 353*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) / 1.0, "int too large to convert to float") 354*4947cdc7SCole Faustassert.fails(lambda: 1.0 / (1<<500<<500<<500), "int too large to convert to float") 355*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) // 1.0, "int too large to convert to float") 356*4947cdc7SCole Faustassert.fails(lambda: 1.0 // (1<<500<<500<<500), "int too large to convert to float") 357*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) % 1.0, "int too large to convert to float") 358*4947cdc7SCole Faustassert.fails(lambda: 1.0 % (1<<500<<500<<500), "int too large to convert to float") 359*4947cdc7SCole Faust 360*4947cdc7SCole Faust 361*4947cdc7SCole Faust# -- int function -- 362*4947cdc7SCole Faustassert.eq(int(0.0), 0) 363*4947cdc7SCole Faustassert.eq(int(1.0), 1) 364*4947cdc7SCole Faustassert.eq(int(1.1), 1) 365*4947cdc7SCole Faustassert.eq(int(0.9), 0) 366*4947cdc7SCole Faustassert.eq(int(-1.1), -1.0) 367*4947cdc7SCole Faustassert.eq(int(-1.0), -1.0) 368*4947cdc7SCole Faustassert.eq(int(-0.9), 0.0) 369*4947cdc7SCole Faustassert.eq(int(1.23e+32), 123000000000000004979083645550592) 370*4947cdc7SCole Faustassert.eq(int(-1.23e-32), 0) 371*4947cdc7SCole Faustassert.eq(int(1.23e-32), 0) 372*4947cdc7SCole Faustassert.fails(lambda: int(float("+Inf")), "cannot convert float infinity to integer") 373*4947cdc7SCole Faustassert.fails(lambda: int(float("-Inf")), "cannot convert float infinity to integer") 374*4947cdc7SCole Faustassert.fails(lambda: int(float("NaN")), "cannot convert float NaN to integer") 375*4947cdc7SCole Faust 376*4947cdc7SCole Faust 377*4947cdc7SCole Faust# hash 378*4947cdc7SCole Faust# Check that equal float and int values have the same internal hash. 379*4947cdc7SCole Faustdef checkhash(): 380*4947cdc7SCole Faust for a in [1.23e100, 1.23e10, 1.23e1, 1.23, 381*4947cdc7SCole Faust 1, 4294967295, 8589934591, 9223372036854775807]: 382*4947cdc7SCole Faust for b in [a, -a, 1/a, -1/a]: 383*4947cdc7SCole Faust f = float(b) 384*4947cdc7SCole Faust i = int(b) 385*4947cdc7SCole Faust if f == i: 386*4947cdc7SCole Faust fh = {f: None} 387*4947cdc7SCole Faust ih = {i: None} 388*4947cdc7SCole Faust if fh != ih: 389*4947cdc7SCole Faust assert.true(False, "{%v: None} != {%v: None}: hashes vary" % fh, ih) 390*4947cdc7SCole Faustcheckhash() 391*4947cdc7SCole Faust 392*4947cdc7SCole Faust# string formatting 393*4947cdc7SCole Faust 394*4947cdc7SCole Faust# %d 395*4947cdc7SCole Faustassert.eq("%d" % 0, "0") 396*4947cdc7SCole Faustassert.eq("%d" % 0.0, "0") 397*4947cdc7SCole Faustassert.eq("%d" % 123, "123") 398*4947cdc7SCole Faustassert.eq("%d" % 123.0, "123") 399*4947cdc7SCole Faustassert.eq("%d" % 1.23e45, "1229999999999999973814869011019624571608236032") 400*4947cdc7SCole Faust# (see below for '%d' % NaN/Inf) 401*4947cdc7SCole Faustassert.eq("%d" % negzero, "0") 402*4947cdc7SCole Faustassert.fails(lambda: "%d" % float("NaN"), "cannot convert float NaN to integer") 403*4947cdc7SCole Faustassert.fails(lambda: "%d" % float("+Inf"), "cannot convert float infinity to integer") 404*4947cdc7SCole Faustassert.fails(lambda: "%d" % float("-Inf"), "cannot convert float infinity to integer") 405*4947cdc7SCole Faust 406*4947cdc7SCole Faust# %e 407*4947cdc7SCole Faustassert.eq("%e" % 0, "0.000000e+00") 408*4947cdc7SCole Faustassert.eq("%e" % 0.0, "0.000000e+00") 409*4947cdc7SCole Faustassert.eq("%e" % 123, "1.230000e+02") 410*4947cdc7SCole Faustassert.eq("%e" % 123.0, "1.230000e+02") 411*4947cdc7SCole Faustassert.eq("%e" % 1.23e45, "1.230000e+45") 412*4947cdc7SCole Faustassert.eq("%e" % -1.23e-45, "-1.230000e-45") 413*4947cdc7SCole Faustassert.eq("%e" % nan, "nan") 414*4947cdc7SCole Faustassert.eq("%e" % inf, "+inf") 415*4947cdc7SCole Faustassert.eq("%e" % neginf, "-inf") 416*4947cdc7SCole Faustassert.eq("%e" % negzero, "-0.000000e+00") 417*4947cdc7SCole Faustassert.fails(lambda: "%e" % "123", "requires float, not str") 418*4947cdc7SCole Faust# %f 419*4947cdc7SCole Faustassert.eq("%f" % 0, "0.000000") 420*4947cdc7SCole Faustassert.eq("%f" % 0.0, "0.000000") 421*4947cdc7SCole Faustassert.eq("%f" % 123, "123.000000") 422*4947cdc7SCole Faustassert.eq("%f" % 123.0, "123.000000") 423*4947cdc7SCole Faust# Note: Starlark/Java emits 1230000000000000000000000000000000000000000000.000000. Why? 424*4947cdc7SCole Faustassert.eq("%f" % 1.23e45, "1229999999999999973814869011019624571608236032.000000") 425*4947cdc7SCole Faustassert.eq("%f" % -1.23e-45, "-0.000000") 426*4947cdc7SCole Faustassert.eq("%f" % nan, "nan") 427*4947cdc7SCole Faustassert.eq("%f" % inf, "+inf") 428*4947cdc7SCole Faustassert.eq("%f" % neginf, "-inf") 429*4947cdc7SCole Faustassert.eq("%f" % negzero, "-0.000000") 430*4947cdc7SCole Faustassert.fails(lambda: "%f" % "123", "requires float, not str") 431*4947cdc7SCole Faust# %g 432*4947cdc7SCole Faustassert.eq("%g" % 0, "0.0") 433*4947cdc7SCole Faustassert.eq("%g" % 0.0, "0.0") 434*4947cdc7SCole Faustassert.eq("%g" % 123, "123.0") 435*4947cdc7SCole Faustassert.eq("%g" % 123.0, "123.0") 436*4947cdc7SCole Faustassert.eq("%g" % 1.110, "1.11") 437*4947cdc7SCole Faustassert.eq("%g" % 1e5, "100000.0") 438*4947cdc7SCole Faustassert.eq("%g" % 1e6, "1e+06") # Note: threshold of scientific notation is 1e17 in Starlark/Java 439*4947cdc7SCole Faustassert.eq("%g" % 1.23e45, "1.23e+45") 440*4947cdc7SCole Faustassert.eq("%g" % -1.23e-45, "-1.23e-45") 441*4947cdc7SCole Faustassert.eq("%g" % nan, "nan") 442*4947cdc7SCole Faustassert.eq("%g" % inf, "+inf") 443*4947cdc7SCole Faustassert.eq("%g" % neginf, "-inf") 444*4947cdc7SCole Faustassert.eq("%g" % negzero, "-0.0") 445*4947cdc7SCole Faust# str uses %g 446*4947cdc7SCole Faustassert.eq(str(0.0), "0.0") 447*4947cdc7SCole Faustassert.eq(str(123.0), "123.0") 448*4947cdc7SCole Faustassert.eq(str(1.23e45), "1.23e+45") 449*4947cdc7SCole Faustassert.eq(str(-1.23e-45), "-1.23e-45") 450*4947cdc7SCole Faustassert.eq(str(nan), "nan") 451*4947cdc7SCole Faustassert.eq(str(inf), "+inf") 452*4947cdc7SCole Faustassert.eq(str(neginf), "-inf") 453*4947cdc7SCole Faustassert.eq(str(negzero), "-0.0") 454*4947cdc7SCole Faustassert.fails(lambda: "%g" % "123", "requires float, not str") 455*4947cdc7SCole Faust 456*4947cdc7SCole Fausti0 = 1 457*4947cdc7SCole Faustf0 = 1.0 458*4947cdc7SCole Faustassert.eq(type(i0), "int") 459*4947cdc7SCole Faustassert.eq(type(f0), "float") 460*4947cdc7SCole Faust 461*4947cdc7SCole Faustops = { 462*4947cdc7SCole Faust '+': lambda x, y: x + y, 463*4947cdc7SCole Faust '-': lambda x, y: x - y, 464*4947cdc7SCole Faust '*': lambda x, y: x * y, 465*4947cdc7SCole Faust '/': lambda x, y: x / y, 466*4947cdc7SCole Faust '//': lambda x, y: x // y, 467*4947cdc7SCole Faust '%': lambda x, y: x % y, 468*4947cdc7SCole Faust} 469*4947cdc7SCole Faust 470*4947cdc7SCole Faust# Check that if either argument is a float, so too is the result. 471*4947cdc7SCole Faustdef checktypes(): 472*4947cdc7SCole Faust want = set(""" 473*4947cdc7SCole Faustint + int = int 474*4947cdc7SCole Faustint + float = float 475*4947cdc7SCole Faustfloat + int = float 476*4947cdc7SCole Faustfloat + float = float 477*4947cdc7SCole Faustint - int = int 478*4947cdc7SCole Faustint - float = float 479*4947cdc7SCole Faustfloat - int = float 480*4947cdc7SCole Faustfloat - float = float 481*4947cdc7SCole Faustint * int = int 482*4947cdc7SCole Faustint * float = float 483*4947cdc7SCole Faustfloat * int = float 484*4947cdc7SCole Faustfloat * float = float 485*4947cdc7SCole Faustint / int = float 486*4947cdc7SCole Faustint / float = float 487*4947cdc7SCole Faustfloat / int = float 488*4947cdc7SCole Faustfloat / float = float 489*4947cdc7SCole Faustint // int = int 490*4947cdc7SCole Faustint // float = float 491*4947cdc7SCole Faustfloat // int = float 492*4947cdc7SCole Faustfloat // float = float 493*4947cdc7SCole Faustint % int = int 494*4947cdc7SCole Faustint % float = float 495*4947cdc7SCole Faustfloat % int = float 496*4947cdc7SCole Faustfloat % float = float 497*4947cdc7SCole Faust"""[1:].splitlines()) 498*4947cdc7SCole Faust for opname in ("+", "-", "*", "/", "%"): 499*4947cdc7SCole Faust for x in [i0, f0]: 500*4947cdc7SCole Faust for y in [i0, f0]: 501*4947cdc7SCole Faust op = ops[opname] 502*4947cdc7SCole Faust got = "%s %s %s = %s" % (type(x), opname, type(y), type(op(x, y))) 503*4947cdc7SCole Faust assert.contains(want, got) 504*4947cdc7SCole Faustchecktypes() 505