src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/builtin_fn_num_test.elvts (about) 1 // When testing numbers with different underlying types, the order is usually 2 // 3 // 1. int 4 // 2. *big.Int (100000000000000000000 is often used) 5 // 3. *big.Rat 6 // 4. float64 7 8 /////// 9 # num # 10 /////// 11 12 ~> num 1 13 ▶ (num 1) 14 ~> num 100000000000000000000 15 ▶ (num 100000000000000000000) 16 ~> num 1/2 17 ▶ (num 1/2) 18 ~> num 0.1 19 ▶ (num 0.1) 20 ~> num (num 1) 21 ▶ (num 1) 22 23 ///////////// 24 # exact-num # 25 ///////////// 26 27 ~> exact-num 1 28 ▶ (num 1) 29 ~> exact-num 0.125 30 ▶ (num 1/8) 31 ~> exact-num inf 32 Exception: bad value: argument here must be finite float, but is +Inf 33 [tty]:1:1-13: exact-num inf 34 35 /////////////// 36 # inexact-num # 37 /////////////// 38 39 ~> inexact-num 1 40 ▶ (num 1.0) 41 ~> inexact-num 1.0 42 ▶ (num 1.0) 43 ~> inexact-num (num 1) 44 ▶ (num 1.0) 45 ~> inexact-num (num 1.0) 46 ▶ (num 1.0) 47 48 ////////////// 49 # Comparison # 50 ////////////// 51 52 ## < ## 53 54 // int 55 ~> < 1 2 3 56 ▶ $true 57 ~> < 1 3 2 58 ▶ $false 59 // *big.Int 60 ~> < 100000000000000000001 100000000000000000002 100000000000000000003 61 ▶ $true 62 ~> < 100000000000000000001 100000000000000000003 100000000000000000002 63 ▶ $false 64 // *big.Rat 65 ~> < 1/4 1/3 1/2 66 ▶ $true 67 ~> < 1/4 1/2 1/3 68 ▶ $false 69 // float64 70 ~> < 1.0 2.0 3.0 71 ▶ $true 72 ~> < 1.0 3.0 2.0 73 ▶ $false 74 75 ## mixed types ## 76 // Only test with <; the other commands share the same code path for handling 77 // mixed types. 78 79 // mixing int and *big.Int 80 ~> < 1 100000000000000000001 81 ▶ $true 82 // mixing int, *big.Int and *big.Rat 83 ~> < 1/2 1 100000000000000000001 84 ▶ $true 85 ~> < 1/2 100000000000000000001 1 86 ▶ $false 87 // mixing int, *big.Rat and float64 88 ~> < 1.0 3/2 2 89 ▶ $true 90 ~> < 1.0 2 3/2 91 ▶ $false 92 93 ## <= ## 94 95 // int 96 ~> <= 1 1 2 97 ▶ $true 98 ~> <= 1 2 1 99 ▶ $false 100 // *big.Int 101 ~> <= 100000000000000000001 100000000000000000001 100000000000000000002 102 ▶ $true 103 ~> <= 100000000000000000001 100000000000000000002 100000000000000000001 104 ▶ $false 105 // *big.Rat 106 ~> <= 1/3 1/3 1/2 107 ▶ $true 108 ~> <= 1/3 1/2 1/1 109 ▶ $true 110 // float64 111 ~> <= 1.0 1.0 2.0 112 ▶ $true 113 ~> <= 1.0 2.0 1.0 114 ▶ $false 115 116 ## == ## 117 118 // int 119 ~> == 1 1 1 120 ▶ $true 121 ~> == 1 2 1 122 ▶ $false 123 // *big.Int 124 ~> == 100000000000000000001 100000000000000000001 100000000000000000001 125 ▶ $true 126 ~> == 100000000000000000001 100000000000000000002 100000000000000000001 127 ▶ $false 128 // *big.Rat 129 ~> == 1/2 1/2 1/2 130 ▶ $true 131 ~> == 1/2 1/3 1/2 132 ▶ $false 133 // float64 134 ~> == 1.0 1.0 1.0 135 ▶ $true 136 ~> == 1.0 2.0 1.0 137 ▶ $false 138 139 ## != ## 140 141 // int 142 ~> != 1 2 143 ▶ $true 144 ~> != 1 1 145 ▶ $false 146 // *big.Int 147 ~> != 100000000000000000001 100000000000000000002 148 ▶ $true 149 ~> != 100000000000000000001 100000000000000000001 150 ▶ $false 151 // *big.Rat 152 ~> != 1/2 1/3 153 ▶ $true 154 ~> != 1/2 1/2 155 ▶ $false 156 // float64 157 ~> != 1.0 2.0 158 ▶ $true 159 ~> != 1.0 1.0 160 ▶ $false 161 // only accepts two arguments 162 ~> != 163 Exception: arity mismatch: arguments must be 2 values, but is 0 values 164 [tty]:1:1-2: != 165 ~> != 1 166 Exception: arity mismatch: arguments must be 2 values, but is 1 value 167 [tty]:1:1-4: != 1 168 ~> != 1 2 3 169 Exception: arity mismatch: arguments must be 2 values, but is 3 values 170 [tty]:1:1-8: != 1 2 3 171 172 ## > ## 173 174 // int 175 ~> > 3 2 1 176 ▶ $true 177 ~> > 3 1 2 178 ▶ $false 179 // *big.Int 180 ~> > 100000000000000000003 100000000000000000002 100000000000000000001 181 ▶ $true 182 ~> > 100000000000000000003 100000000000000000001 100000000000000000002 183 ▶ $false 184 // *big.Rat 185 ~> > 1/2 1/3 1/4 186 ▶ $true 187 ~> > 1/2 1/4 1/3 188 ▶ $false 189 // float64 190 ~> > 3.0 2.0 1.0 191 ▶ $true 192 ~> > 3.0 1.0 2.0 193 ▶ $false 194 195 ## >= ## 196 197 // int 198 ~> >= 3 3 2 199 ▶ $true 200 ~> >= 3 2 3 201 ▶ $false 202 // *big.Int 203 ~> >= 100000000000000000003 100000000000000000003 100000000000000000002 204 ▶ $true 205 ~> >= 100000000000000000003 100000000000000000002 100000000000000000003 206 ▶ $false 207 // *big.Rat 208 ~> >= 1/2 1/2 1/3 209 ▶ $true 210 ~> >= 1/2 1/3 1/2 211 ▶ $false 212 // float64 213 ~> >= 3.0 3.0 2.0 214 ▶ $true 215 ~> >= 3.0 2.0 3.0 216 ▶ $false 217 218 //////////////////// 219 # basic arithmetic # 220 //////////////////// 221 222 ## + ## 223 224 // no argument 225 ~> + 226 ▶ (num 0) 227 // int 228 ~> + 233100 233 229 ▶ (num 233333) 230 // *big.Int 231 ~> + 100000000000000000000 100000000000000000001 232 ▶ (num 200000000000000000001) 233 // *big.Rat 234 ~> + 1/2 1/3 1/4 235 ▶ (num 13/12) 236 // float64 237 ~> + 0.5 0.25 1.0 238 ▶ (num 1.75) 239 240 ## mixing types ## 241 242 // Only test with +; the other commands share the same code path for handling 243 // mixed types. 244 245 // int and *big.Int 246 ~> + 1 2 100000000000000000000 247 ▶ (num 100000000000000000003) 248 // int, *big,Int and *big.Rat 249 ~> + 1/2 1/2 1 100000000000000000000 250 ▶ (num 100000000000000000002) 251 // int, *big.Rat and float64 252 ~> + 0.5 1/4 1 253 ▶ (num 1.75) 254 255 ## - ## 256 257 // no argument is unsupported 258 ~> - 259 Exception: arity mismatch: arguments must be 1 or more values, but is 0 values 260 [tty]:1:1-1: - 261 // one argument is negation 262 ~> - 233 263 ▶ (num -233) 264 ~> - 100000000000000000000 265 ▶ (num -100000000000000000000) 266 ~> - 1/2 267 ▶ (num -1/2) 268 ~> - 1.0 269 ▶ (num -1.0) 270 // int 271 ~> - 20 10 2 272 ▶ (num 8) 273 // *big.Int 274 ~> - 200000000000000000003 100000000000000000001 275 ▶ (num 100000000000000000002) 276 // *big.Rat 277 ~> - 1/2 1/3 278 ▶ (num 1/6) 279 // float64 280 ~> - 2.0 1.0 0.5 281 ▶ (num 0.5) 282 283 ## * ## 284 285 // no argument 286 ~> * 287 ▶ (num 1) 288 // int 289 ~> * 2 7 4 290 ▶ (num 56) 291 // *big.Int 292 ~> * 2 100000000000000000001 293 ▶ (num 200000000000000000002) 294 // *big.Rat 295 ~> * 1/2 1/3 296 ▶ (num 1/6) 297 // float64 298 ~> * 2.0 0.5 1.75 299 ▶ (num 1.75) 300 // 0 * non-infinity 301 ~> * 0 1/2 1.0 302 ▶ (num 0) 303 // 0 * infinity 304 ~> * 0 +Inf 305 ▶ (num NaN) 306 307 ## / ## 308 309 // one argument - inversion 310 ~> / 2 311 ▶ (num 1/2) 312 ~> / 100000000000000000000 313 ▶ (num 1/100000000000000000000) 314 ~> / 2.0 315 ▶ (num 0.5) 316 // int 317 ~> / 233333 353 318 ▶ (num 661) 319 ~> / 3 4 2 320 ▶ (num 3/8) 321 // *big.Int 322 ~> / 200000000000000000000 100000000000000000000 323 ▶ (num 2) 324 ~> / 200000000000000000000 2 325 ▶ (num 100000000000000000000) 326 ~> / 100000000000000000001 100000000000000000000 327 ▶ (num 100000000000000000001/100000000000000000000) 328 // float64 329 ~> / 1.0 2.0 4.0 330 ▶ (num 0.125) 331 ~> / 0 1/2 0.1 332 ▶ (num 0) 333 // anything / 0 334 ~> / 0 0 335 Exception: bad value: divisor must be number other than exact 0, but is exact 0 336 [tty]:1:1-5: / 0 0 337 ~> / 1 0 338 Exception: bad value: divisor must be number other than exact 0, but is exact 0 339 [tty]:1:1-5: / 1 0 340 ~> / 1.0 0 341 Exception: bad value: divisor must be number other than exact 0, but is exact 0 342 [tty]:1:1-7: / 1.0 0 343 344 ## implicit cd with / ## 345 //only-on unix 346 //in-temp-dir 347 //with-deprecation-level 21 348 ~> / 349 Deprecation: implicit cd is deprecated; use cd or location mode instead 350 [tty]:1:1-1: / 351 ~> put $pwd 352 ▶ / 353 354 ## % ## 355 ~> % 23 7 356 ▶ (num 2) 357 ~> % 1 0 358 Exception: bad value: divisor must be number other than exact 0, but is exact 0 359 [tty]:1:1-5: % 1 0 360 // big int support 361 ~> % 10000000000000000000 3 362 ▶ (num 1) 363 // floating point is not supported, even if integer 364 ~> % 10.0 3 365 Exception: bad value: argument must be exact integer, but is (num 10.0) 366 [tty]:1:1-8: % 10.0 3 367 ~> % 10 3.0 368 Exception: bad value: argument must be exact integer, but is (num 3.0) 369 [tty]:1:1-8: % 10 3.0 370 371 /////////// 372 # randint # 373 /////////// 374 375 ~> randint 1 2 376 ▶ (num 1) 377 ~> randint 1 378 ▶ (num 0) 379 ~> var i = (randint 10 100) 380 and (<= 10 $i) (< $i 100) 381 ▶ $true 382 ~> var i = (randint 10) 383 and (<= 0 $i) (< $i 10) 384 ▶ $true 385 // big int is OK 386 ~> var z = (num 10000000000000000000) 387 ~> < (randint $z) $z 388 ▶ $true 389 ~> var low = $z 390 var high = (+ $low 10) 391 var i = (randint $low $high) 392 and (<= $low $i) (< $i $high) 393 ▶ $true 394 395 ## argument checking ## 396 397 ~> randint 2 1 398 Exception: bad value: high value must be larger than 2, but is 1 399 [tty]:1:1-11: randint 2 1 400 ~> var z = (num 10000000000000000000) 401 randint (+ $z 10) $z 402 Exception: bad value: high value must be larger than 10000000000000000010, but is 10000000000000000000 403 [tty]:2:1-20: randint (+ $z 10) $z 404 ~> randint 405 Exception: arity mismatch: arguments must be 1 to 2 values, but is 0 values 406 [tty]:1:1-7: randint 407 ~> randint 1 2 3 408 Exception: arity mismatch: arguments must be 1 to 2 values, but is 3 values 409 [tty]:1:1-13: randint 1 2 3 410 ~> randint 1.0 411 Exception: bad value: argument must be exact integer, but is (num 1.0) 412 [tty]:1:1-11: randint 1.0 413 414 ///////////// 415 # -randseed # 416 ///////////// 417 418 //reseed-afterwards 419 420 // -randseed makes randint deterministic ## 421 ~> fn f { -randseed 0; randint 10 } 422 eq (f) (f) 423 ▶ $true 424 // big int uses a different code path internally, so verify that generating big 425 // int is also deterministic. 426 ~> fn f { -randseed 0; randint 10000000000000000000 } 427 eq (f) (f) 428 ▶ $true 429 // rand is also deterministic 430 ~> fn f { -randseed 0; rand } 431 eq (f) (f) 432 ▶ $true 433 434 ///////// 435 # range # 436 ///////// 437 438 ## argument arity check ## 439 ~> range 440 Exception: arity mismatch: arguments must be 1 to 2 values, but is 0 values 441 [tty]:1:1-5: range 442 ~> range 0 1 2 443 Exception: arity mismatch: arguments must be 1 to 2 values, but is 3 values 444 [tty]:1:1-11: range 0 1 2 445 446 ## int ## 447 // counting up 448 ~> range 3 449 ▶ (num 0) 450 ▶ (num 1) 451 ▶ (num 2) 452 ~> range 1 3 453 ▶ (num 1) 454 ▶ (num 2) 455 // counting down 456 ~> range -1 10 &step=3 457 ▶ (num -1) 458 ▶ (num 2) 459 ▶ (num 5) 460 ▶ (num 8) 461 ~> range 3 -3 462 ▶ (num 3) 463 ▶ (num 2) 464 ▶ (num 1) 465 ▶ (num 0) 466 ▶ (num -1) 467 ▶ (num -2) 468 // invalid step 469 ~> range &step=-1 1 470 Exception: bad value: step must be positive, but is -1 471 [tty]:1:1-16: range &step=-1 1 472 ~> range &step=1 1 0 473 Exception: bad value: step must be negative, but is 1 474 [tty]:1:1-17: range &step=1 1 0 475 // bubbling output error 476 ~> range 2 >&- 477 Exception: port does not support value output 478 [tty]:1:1-11: range 2 >&- 479 480 ## near max/min of int ## 481 // Values near the max/min of int need to be handled carefully to avoid 482 // overflow. Instead of assuming int is 64-bit or 32-bit, test interesting 483 // values for both cases. 484 485 // 2^63-3 to 2^63-1 486 ~> range 9223372036854775805 9223372036854775807 487 ▶ (num 9223372036854775805) 488 ▶ (num 9223372036854775806) 489 ~> range 9223372036854775807 9223372036854775805 490 ▶ (num 9223372036854775807) 491 ▶ (num 9223372036854775806) 492 // -2^63 to -2^63+2 493 ~> range -9223372036854775808 -9223372036854775806 494 ▶ (num -9223372036854775808) 495 ▶ (num -9223372036854775807) 496 ~> range -9223372036854775806 -9223372036854775808 497 ▶ (num -9223372036854775806) 498 ▶ (num -9223372036854775807) 499 // 2^31-3 to 2^31-1 500 ~> range 2147483645 2147483647 501 ▶ (num 2147483645) 502 ▶ (num 2147483646) 503 ~> range 2147483647 2147483645 504 ▶ (num 2147483647) 505 ▶ (num 2147483646) 506 // -2^31 to -2^31+2 507 ~> range -2147483648 -2147483646 508 ▶ (num -2147483648) 509 ▶ (num -2147483647) 510 ~> range -2147483646 -2147483648 511 ▶ (num -2147483646) 512 ▶ (num -2147483647) 513 514 ## *big.Int ## 515 // counting up 516 ~> range 100000000000000000000 100000000000000000003 517 ▶ (num 100000000000000000000) 518 ▶ (num 100000000000000000001) 519 ▶ (num 100000000000000000002) 520 ~> range 100000000000000000000 100000000000000000003 &step=2 521 ▶ (num 100000000000000000000) 522 ▶ (num 100000000000000000002) 523 // counting down 524 ~> range 100000000000000000003 100000000000000000000 525 ▶ (num 100000000000000000003) 526 ▶ (num 100000000000000000002) 527 ▶ (num 100000000000000000001) 528 ~> range 100000000000000000003 100000000000000000000 &step=-2 529 ▶ (num 100000000000000000003) 530 ▶ (num 100000000000000000001) 531 // invalid step 532 ~> range &step=-100000000000000000000 10 533 Exception: bad value: step must be positive, but is -100000000000000000000 534 [tty]:1:1-37: range &step=-100000000000000000000 10 535 ~> range &step=100000000000000000000 10 0 536 Exception: bad value: step must be negative, but is 100000000000000000000 537 [tty]:1:1-38: range &step=100000000000000000000 10 0 538 // bubbling output error 539 ~> range 100000000000000000000 100000000000000000001 >&- 540 Exception: port does not support value output 541 [tty]:1:1-53: range 100000000000000000000 100000000000000000001 >&- 542 543 ## *big.Rat ## 544 // counting up 545 ~> range 23/10 546 ▶ (num 0) 547 ▶ (num 1) 548 ▶ (num 2) 549 ~> range 1/10 23/10 550 ▶ (num 1/10) 551 ▶ (num 11/10) 552 ▶ (num 21/10) 553 ~> range 1/10 9/10 &step=3/10 554 ▶ (num 1/10) 555 ▶ (num 2/5) 556 ▶ (num 7/10) 557 // counting down 558 ~> range 23/10 1/10 559 ▶ (num 23/10) 560 ▶ (num 13/10) 561 ▶ (num 3/10) 562 ~> range 9/10 0/10 &step=-3/10 563 ▶ (num 9/10) 564 ▶ (num 3/5) 565 ▶ (num 3/10) 566 // invalid step 567 ~> range &step=-1/2 10 568 Exception: bad value: step must be positive, but is -1/2 569 [tty]:1:1-19: range &step=-1/2 10 570 ~> range &step=1/2 10 0 571 Exception: bad value: step must be negative, but is 1/2 572 [tty]:1:1-20: range &step=1/2 10 0 573 // bubbling output error 574 ~> range 1/2 3/2 >&- 575 Exception: port does not support value output 576 [tty]:1:1-17: range 1/2 3/2 >&- 577 578 ## float64 ## 579 // counting up 580 ~> range 1.2 581 ▶ (num 0.0) 582 ▶ (num 1.0) 583 ~> range &step=0.5 1 3 584 ▶ (num 1.0) 585 ▶ (num 1.5) 586 ▶ (num 2.0) 587 ▶ (num 2.5) 588 // counting down 589 ~> range 1.2 -1.2 590 ▶ (num 1.2) 591 ▶ (num 0.19999999999999996) 592 ▶ (num -0.8) 593 ~> range &step=-0.5 3 1 594 ▶ (num 3.0) 595 ▶ (num 2.5) 596 ▶ (num 2.0) 597 ▶ (num 1.5) 598 // Nearing the maximum float64 value where x+1 = x. 599 ~> range 9007199254740990.0 +inf 600 ▶ (num 9.00719925474099e+15) 601 ▶ (num 9007199254740991.0) 602 ▶ (num 9007199254740992.0) 603 ~> range 9007199254740992.0 9007199254740990.0 604 ▶ (num 9007199254740992.0) 605 ▶ (num 9007199254740991.0) 606 // invalid step 607 ~> range &step=-0.5 10 608 Exception: bad value: step must be positive, but is -0.5 609 [tty]:1:1-19: range &step=-0.5 10 610 ~> range &step=0.5 10 0 611 Exception: bad value: step must be negative, but is 0.5 612 [tty]:1:1-20: range &step=0.5 10 0 613 // bubbling output error 614 ~> range 1.2 >&- 615 Exception: port does not support value output 616 [tty]:1:1-13: range 1.2 >&-