From f717e3c9d56042b765512394cb9e0f7f549fb9d1 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Thu, 10 Oct 2024 13:15:25 +0800 Subject: [PATCH] more GMP fixes --- spec/std/big/big_float_spec.cr | 44 ++++++++++++++++++++++++---------- src/big/lib_gmp.cr | 23 ++++++++++-------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/spec/std/big/big_float_spec.cr b/spec/std/big/big_float_spec.cr index 23c782aa3de8..4aee9eee51e8 100644 --- a/spec/std/big/big_float_spec.cr +++ b/spec/std/big/big_float_spec.cr @@ -350,8 +350,11 @@ describe "BigFloat" do it { (2.to_big_f ** -7133786264).to_s.should end_with("e-2147483649") } # least power of two with a base-10 exponent less than Int32::MIN it { (10.to_big_f ** 3000000000 * 1.5).to_s.should end_with("e+3000000000") } it { (10.to_big_f ** -3000000000 * 1.5).to_s.should end_with("e-3000000000") } - it { (10.to_big_f ** 10000000000 * 1.5).to_s.should end_with("e+10000000000") } - it { (10.to_big_f ** -10000000000 * 1.5).to_s.should end_with("e-10000000000") } + + {% unless flag?(:win32) && flag?(:gnu) %} + it { (10.to_big_f ** 10000000000 * 1.5).to_s.should end_with("e+10000000000") } + it { (10.to_big_f ** -10000000000 * 1.5).to_s.should end_with("e-10000000000") } + {% end %} end describe "#inspect" do @@ -558,8 +561,12 @@ describe "BigFloat Math" do Math.ilogb(0.2.to_big_f).should eq(-3) Math.ilogb(123.45.to_big_f).should eq(6) Math.ilogb(2.to_big_f ** 1_000_000_000).should eq(1_000_000_000) - Math.ilogb(2.to_big_f ** 100_000_000_000).should eq(100_000_000_000) - Math.ilogb(2.to_big_f ** -100_000_000_000).should eq(-100_000_000_000) + + {% unless flag?(:win32) && flag?(:gnu) %} + Math.ilogb(2.to_big_f ** 100_000_000_000).should eq(100_000_000_000) + Math.ilogb(2.to_big_f ** -100_000_000_000).should eq(-100_000_000_000) + {% end %} + expect_raises(ArgumentError) { Math.ilogb(0.to_big_f) } end @@ -567,8 +574,12 @@ describe "BigFloat Math" do Math.logb(0.2.to_big_f).should eq(-3.to_big_f) Math.logb(123.45.to_big_f).should eq(6.to_big_f) Math.logb(2.to_big_f ** 1_000_000_000).should eq(1_000_000_000.to_big_f) - Math.logb(2.to_big_f ** 100_000_000_000).should eq(100_000_000_000.to_big_f) - Math.logb(2.to_big_f ** -100_000_000_000).should eq(-100_000_000_000.to_big_f) + + {% unless flag?(:win32) && flag?(:gnu) %} + Math.logb(2.to_big_f ** 100_000_000_000).should eq(100_000_000_000.to_big_f) + Math.logb(2.to_big_f ** -100_000_000_000).should eq(-100_000_000_000.to_big_f) + {% end %} + expect_raises(ArgumentError) { Math.logb(0.to_big_f) } end @@ -576,24 +587,33 @@ describe "BigFloat Math" do Math.ldexp(0.2.to_big_f, 2).should eq(0.8.to_big_f) Math.ldexp(0.2.to_big_f, -2).should eq(0.05.to_big_f) Math.ldexp(1.to_big_f, 1_000_000_000).should eq(2.to_big_f ** 1_000_000_000) - Math.ldexp(1.to_big_f, 100_000_000_000).should eq(2.to_big_f ** 100_000_000_000) - Math.ldexp(1.to_big_f, -100_000_000_000).should eq(0.5.to_big_f ** 100_000_000_000) + + {% unless flag?(:win32) && flag?(:gnu) %} + Math.ldexp(1.to_big_f, 100_000_000_000).should eq(2.to_big_f ** 100_000_000_000) + Math.ldexp(1.to_big_f, -100_000_000_000).should eq(0.5.to_big_f ** 100_000_000_000) + {% end %} end it ".scalbn" do Math.scalbn(0.2.to_big_f, 2).should eq(0.8.to_big_f) Math.scalbn(0.2.to_big_f, -2).should eq(0.05.to_big_f) Math.scalbn(1.to_big_f, 1_000_000_000).should eq(2.to_big_f ** 1_000_000_000) - Math.scalbn(1.to_big_f, 100_000_000_000).should eq(2.to_big_f ** 100_000_000_000) - Math.scalbn(1.to_big_f, -100_000_000_000).should eq(0.5.to_big_f ** 100_000_000_000) + + {% unless flag?(:win32) && flag?(:gnu) %} + Math.scalbn(1.to_big_f, 100_000_000_000).should eq(2.to_big_f ** 100_000_000_000) + Math.scalbn(1.to_big_f, -100_000_000_000).should eq(0.5.to_big_f ** 100_000_000_000) + {% end %} end it ".scalbln" do Math.scalbln(0.2.to_big_f, 2).should eq(0.8.to_big_f) Math.scalbln(0.2.to_big_f, -2).should eq(0.05.to_big_f) Math.scalbln(1.to_big_f, 1_000_000_000).should eq(2.to_big_f ** 1_000_000_000) - Math.scalbln(1.to_big_f, 100_000_000_000).should eq(2.to_big_f ** 100_000_000_000) - Math.scalbln(1.to_big_f, -100_000_000_000).should eq(0.5.to_big_f ** 100_000_000_000) + + {% unless flag?(:win32) && flag?(:gnu) %} + Math.scalbln(1.to_big_f, 100_000_000_000).should eq(2.to_big_f ** 100_000_000_000) + Math.scalbln(1.to_big_f, -100_000_000_000).should eq(0.5.to_big_f ** 100_000_000_000) + {% end %} end it ".frexp" do diff --git a/src/big/lib_gmp.cr b/src/big/lib_gmp.cr index 715f83bd0d1a..7368cb0e9fb6 100644 --- a/src/big/lib_gmp.cr +++ b/src/big/lib_gmp.cr @@ -26,17 +26,19 @@ lib LibGMP alias Double = LibC::Double alias BitcntT = UI - {% if flag?(:win32) && !flag?(:gnu) && flag?(:bits64) %} - alias MpExp = LibC::Long + alias MpExp = LibC::Long + + {% if flag?(:win32) && !flag?(:gnu) %} alias MpSize = LibC::LongLong - alias MpLimb = LibC::ULongLong - {% elsif flag?(:bits64) %} - alias MpExp = Int64 - alias MpSize = LibC::Long - alias MpLimb = LibC::ULong {% else %} - alias MpExp = Int32 alias MpSize = LibC::Long + {% end %} + + # NOTE: this assumes GMP is configured by build time to define + # `_LONG_LONG_LIMB=1` on Windows + {% if flag?(:win32) %} + alias MpLimb = LibC::ULongLong + {% else %} alias MpLimb = LibC::ULong {% end %} @@ -149,11 +151,12 @@ lib LibGMP # # Miscellaneous Functions - fun fits_ulong_p = __gmpz_fits_ulong_p(op : MPZ*) : Int - fun fits_slong_p = __gmpz_fits_slong_p(op : MPZ*) : Int {% if flag?(:win32) && !flag?(:gnu) %} fun fits_ui_p = __gmpz_fits_ui_p(op : MPZ*) : Int fun fits_si_p = __gmpz_fits_si_p(op : MPZ*) : Int + {% else %} + fun fits_ulong_p = __gmpz_fits_ulong_p(op : MPZ*) : Int + fun fits_slong_p = __gmpz_fits_slong_p(op : MPZ*) : Int {% end %} # # Special Functions