Skip to content

Commit

Permalink
more GMP fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Oct 10, 2024
1 parent 6f8f030 commit f717e3c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 22 deletions.
44 changes: 32 additions & 12 deletions spec/std/big/big_float_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -558,42 +561,59 @@ 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

it ".logb" 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

it ".ldexp" 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
Expand Down
23 changes: 13 additions & 10 deletions src/big/lib_gmp.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f717e3c

Please sign in to comment.