From 3e423722c6571d8c2bc495005e60cf308058d5f3 Mon Sep 17 00:00:00 2001 From: Mike Beller Date: Thu, 4 Jun 2020 18:27:48 -0400 Subject: [PATCH] Actually got the comparisons working for s64 (still need to fix u64) --- src/core/inttypes.c | 21 ++++++++++++++++++--- test/suite0.janet | 7 ++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/core/inttypes.c b/src/core/inttypes.c index 4b72f07d..713ada4d 100644 --- a/src/core/inttypes.c +++ b/src/core/inttypes.c @@ -197,6 +197,10 @@ static Janet cfun_it_u64_new(int32_t argc, Janet *argv) { return janet_wrap_u64(janet_unwrap_u64(argv[0])); } +static int64_t compare_double(double x, double y) { + return (x < y) ? -1 : ((x > y) ? 1 : 0); +} + static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); if (janet_is_int(argv[0]) != JANET_INT_S64) @@ -206,9 +210,20 @@ static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) { default: break; case JANET_NUMBER : { - double y = round(janet_unwrap_number(argv[1])); - double dx = round((double) x); //double trouble? - return janet_wrap_number(dx < y ? -1 : (dx > y ? 1 : 0)); + double y = janet_unwrap_number(argv[1]); + if (isnan(y)) { + return janet_wrap_number(0); // per python compare function + } else if ((y > ((double) -MAX_INT_IN_DBL)) && (y < ((double) MAX_INT_IN_DBL))) { + double dx = (double) x; + return janet_wrap_number(compare_double(dx, y)); + } else if (y > ((double) INT64_MAX)) { + return janet_wrap_number(1); + } else if (y < ((double) INT64_MIN)) { + return janet_wrap_number(-1); + } else { + int64_t yi = (int64_t) y; + return janet_wrap_number((x < yi) ? -1 : ((x > yi) ? 1 : 0)); + } } case JANET_ABSTRACT: { void *abst = janet_unwrap_abstract(argv[1]); diff --git a/test/suite0.janet b/test/suite0.janet index db2ba21e..bbb97a24 100644 --- a/test/suite0.janet +++ b/test/suite0.janet @@ -389,7 +389,7 @@ # test polymorphic compare with int/u64 and int/s64 (def MAX_INT_64_STRING "9223372036854775807") (def MAX_UINT_64_STRING "18446744073709551615") -(def MAX_INT_IN_DBL_STRING "9007199254740992") +(def MAX_INT_IN_DBL_STRING "9007199254740991") (assert (= 0 (compare (int/u64 3) 3)) "compare number to int/u64") (assert (= -1 (compare (int/u64 3) 4)) "compare number to int/u64 less") (assert (= 0 (compare 3 (int/u64 3))) "compare number to int/u64") @@ -410,10 +410,7 @@ (assert (= -1 (compare (int/s64 MAX_INT_64_STRING) (int/u64 MAX_UINT_64_STRING))) "compare big ints") (assert (= 0 (compare (int/s64 MAX_INT_IN_DBL_STRING) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (1)") (assert (= 0 (compare (int/u64 MAX_INT_IN_DBL_STRING) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (2)") -(assert (= 1 (compare (+ 2 (int/u64 MAX_INT_IN_DBL_STRING)) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (3)") -# Beware: This is a horrible effect of comparing doubles to integers -# int/64(MAX+1) should compare greater than the double, (but doesn't due to precision) -(assert (= 0 (compare (+ 1 (int/u64 MAX_INT_IN_DBL_STRING)) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (3)") +(assert (= 1 (compare (+ 1 (int/u64 MAX_INT_IN_DBL_STRING)) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (3)") (end-suite)