aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtins/integers.c3
-rw-r--r--builtins/integers.h2
-rw-r--r--compile.c4
-rw-r--r--test/integers.tm19
4 files changed, 25 insertions, 3 deletions
diff --git a/builtins/integers.c b/builtins/integers.c
index 776fdc3d..53e38aab 100644
--- a/builtins/integers.c
+++ b/builtins/integers.c
@@ -23,7 +23,8 @@ public void Int$init_random(long seed)
public Int_t Int$from_i64(int64_t i)
{
- if (i == (int32_t)i) return (Int_t){.small=(i*4)+1};
+ int64_t z = i<<2;
+ if (z == (int32_t)z) return (Int_t){.small=z+1};
mpz_t result;
mpz_init_set_si(result, i);
return Int$from_mpz(result);
diff --git a/builtins/integers.h b/builtins/integers.h
index f9051ff5..5566c549 100644
--- a/builtins/integers.h
+++ b/builtins/integers.h
@@ -60,7 +60,7 @@ Range_t Int$to(Int_t from, Int_t to);
Int_t Int$from_text(CORD text);
Int_t Int$abs(Int_t x);
-#define BIGGEST_SMALL_INT ((1<<30)-1)
+#define BIGGEST_SMALL_INT (536870911)
#define Int$from_mpz(mpz) (\
mpz_cmpabs_ui(mpz, BIGGEST_SMALL_INT) <= 0 ? ({ \
diff --git a/compile.c b/compile.c
index 8c7dc6df..1053b739 100644
--- a/compile.c
+++ b/compile.c
@@ -1386,8 +1386,10 @@ CORD compile(env_t *env, ast_t *ast)
switch (Match(ast, Int)->bits) {
case 0:
- if ((mpz_cmp_si(i, BIGGEST_SMALL_INT) < 0) && (mpz_cmp_si(i, -BIGGEST_SMALL_INT) > 0)) {
+ if (mpz_cmpabs_ui(i, BIGGEST_SMALL_INT) <= 0) {
return CORD_asprintf("I(%s)", str);
+ } else if (mpz_cmp_si(i, INT64_MAX) <= 0 && mpz_cmp_si(i, INT64_MIN) >= 0) {
+ return CORD_asprintf("Int$from_i64(%s)", str);
} else {
return CORD_asprintf("Int$from_text(\"%s\")", str);
}
diff --git a/test/integers.tm b/test/integers.tm
index c92cbddf..55683500 100644
--- a/test/integers.tm
+++ b/test/integers.tm
@@ -56,3 +56,22 @@ func main():
>> Int(2.1)
= 2 : Int
+
+ do:
+ >> small_int := 1
+ = 1
+ >> max_small_int := 536870911
+ = 536870911
+ >> max_i64 := 536870912
+ = 536870912
+ >> super_big := 9999999999999999999999
+ = 9999999999999999999999
+ >> max_small_int + 1
+ = 536870912
+
+ >> max_small_int + max_small_int
+ = 1073741822
+
+ >> super_big + 1
+ = 10000000000000000000000
+