Skip to content

Commit d1960a5

Browse files
akzhanRX14
authored andcommittedSep 1, 2017
Additions to Big arithmetics (#4653)
* Additions to Big arithmetics. Follows #4560. * Follow @RX14 review (single line blocks, extract mantissa bits constants). * Int cast is implicit here. * Format src/big/big_rational.cr * BigRational is not float, and frexp should be not used on it. * frexp should not be used on BigInt. * rework BigFloat./ * rename bsi, bfsi, bsf, bfsf etc. in spec. * rework def BigFloat.<=>(other : Int) * Simplify a bit, thanks to @RX14 * just remove commen. looks like single Number constructor looks OK in every case. * more verbose naming for used variables. * just explanation of workaround, refs #4897 * For now overloads work (i don't know why). * dedup * Forward declarations of Big Arithmentics types.
1 parent 842548e commit d1960a5

File tree

8 files changed

+331
-20
lines changed

8 files changed

+331
-20
lines changed
 

Diff for: ‎spec/std/big/big_float_spec.cr

+72
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,62 @@ require "spec"
22
require "big_float"
33

44
describe "BigFloat" do
5+
describe "new" do
6+
string_of_integer_value = "123456789012345678901"
7+
bigfloat_of_integer_value = BigFloat.new(string_of_integer_value)
8+
string_of_float_value = "1234567890.12345678901"
9+
bigfloat_of_float_value = BigFloat.new(string_of_float_value)
10+
11+
it "new(String)" do
12+
bigfloat_of_integer_value.to_s.should eq(string_of_integer_value)
13+
bigfloat_of_float_value.to_s.should eq(string_of_float_value)
14+
end
15+
16+
it "new(BigInt)" do
17+
bigfloat_on_bigint_value = BigFloat.new(BigInt.new(string_of_integer_value))
18+
bigfloat_on_bigint_value.should eq(bigfloat_of_integer_value)
19+
bigfloat_on_bigint_value.to_s.should eq(string_of_integer_value)
20+
end
21+
22+
it "new(BigRational)" do
23+
bigfloat_on_bigrational_value = BigFloat.new(BigRational.new(1, 3))
24+
bigfloat_on_bigrational_value.should eq(BigFloat.new(1) / BigFloat.new(3))
25+
end
26+
27+
it "new(BigFloat)" do
28+
BigFloat.new(bigfloat_of_integer_value).should eq(bigfloat_of_integer_value)
29+
BigFloat.new(bigfloat_of_float_value).should eq(bigfloat_of_float_value)
30+
end
31+
32+
it "new(Int)" do
33+
BigFloat.new(1_u8).to_s.should eq("1")
34+
BigFloat.new(1_u16).to_s.should eq("1")
35+
BigFloat.new(1_u32).to_s.should eq("1")
36+
BigFloat.new(1_u64).to_s.should eq("1")
37+
BigFloat.new(1_i8).to_s.should eq("1")
38+
BigFloat.new(1_i16).to_s.should eq("1")
39+
BigFloat.new(1_i32).to_s.should eq("1")
40+
BigFloat.new(1_i64).to_s.should eq("1")
41+
BigFloat.new(-1_i8).to_s.should eq("-1")
42+
BigFloat.new(-1_i16).to_s.should eq("-1")
43+
BigFloat.new(-1_i32).to_s.should eq("-1")
44+
BigFloat.new(-1_i64).to_s.should eq("-1")
45+
46+
BigFloat.new(255_u8).to_s.should eq("255")
47+
BigFloat.new(65535_u16).to_s.should eq("65535")
48+
BigFloat.new(4294967295_u32).to_s.should eq("4294967295")
49+
BigFloat.new(18446744073709551615_u64).to_s.should eq("18446744073709551615")
50+
BigFloat.new(127_i8).to_s.should eq("127")
51+
BigFloat.new(32767_i16).to_s.should eq("32767")
52+
BigFloat.new(2147483647_i32).to_s.should eq("2147483647")
53+
BigFloat.new(9223372036854775807_i64).to_s.should eq("9223372036854775807")
54+
BigFloat.new(-128_i8).to_s.should eq("-128")
55+
BigFloat.new(-32768_i16).to_s.should eq("-32768")
56+
BigFloat.new(-2147483648_i32).to_s.should eq("-2147483648")
57+
BigFloat.new(-9223372036854775808_i64).to_s.should eq("-9223372036854775808")
58+
end
59+
end
60+
561
describe "-@" do
662
bf = "0.12345".to_big_f
763
it { (-bf).to_s.should eq("-0.12345") }
@@ -40,6 +96,8 @@ describe "BigFloat" do
4096
it { ("-5.5".to_big_f / "5.5".to_big_f).to_s.should eq("-1") }
4197
it { ("5.5".to_big_f / "-5.5".to_big_f).to_s.should eq("-1") }
4298
expect_raises(DivisionByZero) { 0.1.to_big_f / 0 }
99+
it { ("5.5".to_big_f / 16_u64).to_s.should eq("0.34375") }
100+
it { ("5.5".to_big_f / 16_u8).to_s.should eq("0.34375") }
43101
end
44102

45103
describe "**" do
@@ -65,6 +123,13 @@ describe "BigFloat" do
65123
describe "floor" do
66124
it { 2.1.to_big_f.floor.should eq(2) }
67125
it { 2.9.to_big_f.floor.should eq(2) }
126+
it { -2.9.to_big_f.floor.should eq(-3) }
127+
end
128+
129+
describe "trunc" do
130+
it { 2.1.to_big_f.trunc.should eq(2) }
131+
it { 2.9.to_big_f.trunc.should eq(2) }
132+
it { -2.9.to_big_f.trunc.should eq(-2) }
68133
end
69134

70135
describe "to_f" do
@@ -92,6 +157,7 @@ describe "BigFloat" do
92157
it { "12345678.87654321".to_big_f.to_s.should eq("12345678.87654321") }
93158
it { "9.000000000000987".to_big_f.to_s.should eq("9.000000000000987") }
94159
it { "12345678901234567".to_big_f.to_s.should eq("12345678901234567") }
160+
it { "1234567890123456789".to_big_f.to_s.should eq("1234567890123456789") }
95161
end
96162

97163
describe "#inspect" do
@@ -108,3 +174,9 @@ describe "BigFloat" do
108174
x.clone.should eq(x)
109175
end
110176
end
177+
178+
describe "BigFloat Math" do
179+
it "frexp" do
180+
Math.frexp(0.2.to_big_f).should eq({0.8, -2})
181+
end
182+
end

Diff for: ‎spec/std/big/big_int_spec.cr

+28
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,29 @@ describe "BigInt" do
5353
[1.1, 1.to_big_i, 3.to_big_i, 2.2].sort.should eq([1, 1.1, 2.2, 3])
5454
end
5555

56+
it "divides and calculs the modulo" do
57+
11.to_big_i.divmod(3.to_big_i).should eq({3, 2})
58+
11.to_big_i.divmod(-3.to_big_i).should eq({-4, -1})
59+
60+
11.to_big_i.divmod(3_i32).should eq({3, 2})
61+
11.to_big_i.divmod(-3_i32).should eq({-4, -1})
62+
63+
10.to_big_i.divmod(2).should eq({5, 0})
64+
11.to_big_i.divmod(2).should eq({5, 1})
65+
66+
10.to_big_i.divmod(2.to_big_i).should eq({5, 0})
67+
11.to_big_i.divmod(2.to_big_i).should eq({5, 1})
68+
69+
10.to_big_i.divmod(-2).should eq({-5, 0})
70+
11.to_big_i.divmod(-2).should eq({-6, -1})
71+
72+
-10.to_big_i.divmod(2).should eq({-5, 0})
73+
-11.to_big_i.divmod(2).should eq({-6, 1})
74+
75+
-10.to_big_i.divmod(-2).should eq({5, 0})
76+
-11.to_big_i.divmod(-2).should eq({5, -1})
77+
end
78+
5679
it "adds" do
5780
(1.to_big_i + 2.to_big_i).should eq(3.to_big_i)
5881
(1.to_big_i + 2).should eq(3.to_big_i)
@@ -222,6 +245,11 @@ describe "BigInt" do
222245
a.to_s(32).should eq(d)
223246
end
224247

248+
it "does to_big_f" do
249+
a = BigInt.new("1234567890123456789")
250+
a.to_big_f.should eq(BigFloat.new("1234567890123456789.0"))
251+
end
252+
225253
describe "#inspect" do
226254
it { "2".to_big_i.inspect.should eq("2_big_i") }
227255
end

Diff for: ‎spec/std/big/big_rational_spec.cr

+14
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,24 @@ describe BigRational do
7272
r.to_f32.should be_close(f, 0.001)
7373
end
7474

75+
it "#to_big_f" do
76+
r = br(10, 3)
77+
f = 10.to_big_f / 3.to_big_f
78+
r.to_big_f.should be_close(f, 0.001)
79+
end
80+
7581
it "Int#to_big_r" do
7682
3.to_big_r.should eq(br(3, 1))
7783
end
7884

85+
it "Float32#to_big_r" do
86+
0.3333333333333333333333_f32.to_big_r.should eq(br(11184811, 33554432))
87+
end
88+
89+
it "Float64#to_big_r" do
90+
0.3333333333333333333333_f64.to_big_r.should eq(br(6004799503160661, 18014398509481984))
91+
end
92+
7993
it "#<=>(:BigRational) and Comparable" do
8094
a = br(11, 3)
8195
l = br(10, 3)

Diff for: ‎src/big.cr

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
# :nodoc: Forward declarations
2+
struct BigInt < Int
3+
end
4+
5+
struct BigFloat < Float
6+
end
7+
8+
struct BigRational < Number
9+
end
10+
111
require "./big/lib_gmp"
212
require "./big/big_int"
313
require "./big/big_float"

Diff for: ‎src/big/big_float.cr

+76-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,47 @@ struct BigFloat < Float
1717
LibGMP.mpf_init_set_str(out @mpf, str, 10)
1818
end
1919

20+
def initialize(num : BigInt)
21+
LibGMP.mpf_init(out @mpf)
22+
LibGMP.mpf_set_z(self, num)
23+
end
24+
25+
def initialize(num : BigRational)
26+
LibGMP.mpf_init(out @mpf)
27+
LibGMP.mpf_set_q(self, num)
28+
end
29+
30+
def initialize(num : BigFloat)
31+
LibGMP.mpf_init(out @mpf)
32+
LibGMP.mpf_set(self, num)
33+
end
34+
35+
def initialize(num : Int8 | Int16 | Int32)
36+
LibGMP.mpf_init_set_si(out @mpf, num)
37+
end
38+
39+
def initialize(num : UInt8 | UInt16 | UInt32)
40+
LibGMP.mpf_init_set_ui(out @mpf, num)
41+
end
42+
43+
def initialize(num : Int64)
44+
if LibGMP::Long == Int64
45+
LibGMP.mpf_init_set_si(out @mpf, num)
46+
else
47+
LibGMP.mpf_init(out @mpf)
48+
LibGMP.mpf_set_z(self, num.to_big_i)
49+
end
50+
end
51+
52+
def initialize(num : UInt64)
53+
if LibGMP::ULong == UInt64
54+
LibGMP.mpf_init_set_ui(out @mpf, num)
55+
else
56+
LibGMP.mpf_init(out @mpf)
57+
LibGMP.mpf_set_z(self, num.to_big_i)
58+
end
59+
end
60+
2061
def initialize(num : Number)
2162
LibGMP.mpf_init_set_d(out @mpf, num.to_f64)
2263
end
@@ -51,16 +92,22 @@ struct BigFloat < Float
5192
LibGMP.mpf_cmp(self, other)
5293
end
5394

54-
def <=>(other : Float)
55-
LibGMP.mpf_cmp_d(self, other.to_f64)
95+
def <=>(other : BigInt)
96+
LibGMP.mpf_cmp_z(self, other)
5697
end
5798

58-
def <=>(other : Int::Signed)
59-
LibGMP.mpf_cmp_si(self, other.to_i64)
99+
def <=>(other : Float32 | Float64)
100+
LibGMP.mpf_cmp_d(self, other.to_f64)
60101
end
61102

62-
def <=>(other : Int::Unsigned)
63-
LibGMP.mpf_cmp_ui(self, other.to_u64)
103+
def <=>(other : Number)
104+
if other.is_a?(Int8 | Int16 | Int32) || (LibGMP::Long == Int64 && other.is_a?(Int64))
105+
LibGMP.mpf_cmp_si(self, other)
106+
elsif other.is_a?(UInt8 | UInt16 | UInt32) || (LibGMP::ULong == UInt64 && other.is_a?(UInt64))
107+
LibGMP.mpf_cmp_ui(self, other)
108+
else
109+
LibGMP.mpf_cmp(self, other.to_big_f)
110+
end
64111
end
65112

66113
def -
@@ -81,7 +128,11 @@ struct BigFloat < Float
81128

82129
def /(other : Number)
83130
raise DivisionByZero.new if other == 0
84-
BigFloat.new { |mpf| LibGMP.mpf_div(mpf, self, other.to_big_f) }
131+
if other.is_a?(UInt8 | UInt16 | UInt32) || (LibGMP::ULong == UInt64 && other.is_a?(UInt64))
132+
BigFloat.new { |mpf| LibGMP.mpf_div_ui(mpf, self, other) }
133+
else
134+
BigFloat.new { |mpf| LibGMP.mpf_div(mpf, self, other.to_big_f) }
135+
end
85136
end
86137

87138
def **(other : Int)
@@ -100,6 +151,10 @@ struct BigFloat < Float
100151
BigFloat.new { |mpf| LibGMP.mpf_floor(mpf, self) }
101152
end
102153

154+
def trunc
155+
BigFloat.new { |mpf| LibGMP.mpf_trunc(mpf, self) }
156+
end
157+
103158
def to_f64
104159
LibGMP.mpf_get_d(self)
105160
end
@@ -222,3 +277,17 @@ class String
222277
BigFloat.new(self)
223278
end
224279
end
280+
281+
module Math
282+
def frexp(value : BigFloat)
283+
LibGMP.mpf_get_d_2exp(out exp, value) # we need BigFloat frac, so will skip Float64 one.
284+
frac = BigFloat.new do |mpf|
285+
if exp >= 0
286+
LibGMP.mpf_div_2exp(mpf, value, exp)
287+
else
288+
LibGMP.mpf_mul_2exp(mpf, value, -exp)
289+
end
290+
end
291+
{frac, exp}
292+
end
293+
end

Diff for: ‎src/big/big_int.cr

+73-8
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,35 @@ struct BigInt < Int
195195
unsafe_truncated_mod(other)
196196
end
197197

198+
def divmod(number : BigInt)
199+
check_division_by_zero number
200+
201+
unsafe_floored_divmod(number)
202+
end
203+
204+
def divmod(number : LibGMP::ULong)
205+
check_division_by_zero number
206+
unsafe_floored_divmod(number)
207+
end
208+
209+
def divmod(number : Int::Signed)
210+
check_division_by_zero number
211+
if number > 0 && number <= LibC::Long::MAX
212+
unsafe_floored_divmod(LibGMP::ULong.new(number))
213+
else
214+
divmod(number.to_big_i)
215+
end
216+
end
217+
218+
def divmod(number : Int::Unsigned)
219+
check_division_by_zero number
220+
if number <= LibC::ULong::MAX
221+
unsafe_floored_divmod(LibGMP::ULong.new(number))
222+
else
223+
divmod(number.to_big_i)
224+
end
225+
end
226+
198227
def unsafe_floored_mod(other : BigInt) : BigInt
199228
BigInt.new { |mpz| LibGMP.fdiv_r(mpz, self, other) }
200229
end
@@ -211,6 +240,30 @@ struct BigInt < Int
211240
BigInt.new { |mpz| LibGMP.tdiv_r_ui(mpz, self, other.abs) }
212241
end
213242

243+
def unsafe_floored_divmod(number : BigInt)
244+
the_q = BigInt.new
245+
the_r = BigInt.new { |r| LibGMP.fdiv_qr(the_q, r, self, number) }
246+
{the_q, the_r}
247+
end
248+
249+
def unsafe_floored_divmod(number : LibGMP::ULong)
250+
the_q = BigInt.new
251+
the_r = BigInt.new { |r| LibGMP.fdiv_qr_ui(the_q, r, self, number) }
252+
{the_q, the_r}
253+
end
254+
255+
def unsafe_truncated_divmod(number : BigInt)
256+
the_q = BigInt.new
257+
the_r = BigInt.new { |r| LibGMP.tdiv_qr(the_q, r, self, number) }
258+
{the_q, the_r}
259+
end
260+
261+
def unsafe_truncated_divmod(number : LibGMP::ULong)
262+
the_q = BigInt.new
263+
the_r = BigInt.new { |r| LibGMP.tdiv_qr_ui(the_q, r, self, number) }
264+
{the_q, the_r}
265+
end
266+
214267
def ~ : BigInt
215268
BigInt.new { |mpz| LibGMP.com(mpz, self) }
216269
end
@@ -311,39 +364,47 @@ struct BigInt < Int
311364
end
312365

313366
def to_i8
314-
to_i64.to_i8
367+
to_i32.to_i8
315368
end
316369

317370
def to_i16
318-
to_i64.to_i16
371+
to_i32.to_i16
319372
end
320373

321374
def to_i32
322-
to_i64.to_i32
375+
LibGMP.get_si(self).to_i32
323376
end
324377

325378
def to_i64
326-
LibGMP.get_si(self)
379+
if LibGMP::Long == Int64 || (self <= Int32::MAX && self >= Int32::MIN)
380+
LibGMP.get_si(self).to_i64
381+
else
382+
to_s.to_i64
383+
end
327384
end
328385

329386
def to_u
330387
to_u32
331388
end
332389

333390
def to_u8
334-
to_u64.to_u8
391+
to_u32.to_u8
335392
end
336393

337394
def to_u16
338-
to_u64.to_u16
395+
to_u32.to_u16
339396
end
340397

341398
def to_u32
342-
to_u64.to_u32
399+
LibGMP.get_ui(self).to_u32
343400
end
344401

345402
def to_u64
346-
LibGMP.get_ui(self).to_u64
403+
if LibGMP::ULong == UInt64 || (self <= UInt32::MAX && self >= UInt32::MIN)
404+
LibGMP.get_ui(self).to_u64
405+
else
406+
to_s.to_u64
407+
end
347408
end
348409

349410
def to_f
@@ -362,6 +423,10 @@ struct BigInt < Int
362423
self
363424
end
364425

426+
def to_big_f
427+
BigFloat.new { |mpf| LibGMP.mpf_set_z(mpf, mpz) }
428+
end
429+
365430
def clone
366431
self
367432
end

Diff for: ‎src/big/big_rational.cr

+33-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require "big"
88
# ```
99
# require "big_rational"
1010
#
11-
# r = BigRational.new(BigInt.new(7), BigInt.new(3))
11+
# r = BigRational.new(7.to_big_i, 3.to_big_i)
1212
# r.to_s # => "7/3"
1313
#
1414
# r = BigRational.new(3, -9)
@@ -21,6 +21,9 @@ struct BigRational < Number
2121
include Comparable(Int)
2222
include Comparable(Float)
2323

24+
private MANTISSA_BITS = 53
25+
private MANTISSA_SHIFT = (1_i64 << MANTISSA_BITS).to_f64
26+
2427
# Create a new `BigRational`.
2528
#
2629
# If *denominator* is 0, this will raise an exception.
@@ -41,6 +44,21 @@ struct BigRational < Number
4144
initialize(num, 1)
4245
end
4346

47+
# Creates a exact representation of float as rational.
48+
def initialize(num : Float)
49+
# It ensures that `BigRational.new(f) == f`
50+
# It relies on fact, that mantissa is at most 53 bits
51+
frac, exp = Math.frexp num
52+
ifrac = (frac.to_f64 * MANTISSA_SHIFT).to_i64
53+
exp -= MANTISSA_BITS
54+
initialize ifrac, 1
55+
if exp >= 0
56+
LibGMP.mpq_mul_2exp(out @mpq, self, exp)
57+
else
58+
LibGMP.mpq_div_2exp(out @mpq, self, -exp)
59+
end
60+
end
61+
4462
# :nodoc:
4563
def initialize(@mpq : LibGMP::MPQ)
4664
end
@@ -64,8 +82,12 @@ struct BigRational < Number
6482
LibGMP.mpq_cmp(mpq, other)
6583
end
6684

85+
def <=>(other : Float32 | Float64)
86+
self <=> BigRational.new(other)
87+
end
88+
6789
def <=>(other : Float)
68-
self.to_f <=> other
90+
to_big_f <=> other.to_big_f
6991
end
7092

7193
def <=>(other : Int)
@@ -156,6 +178,10 @@ struct BigRational < Number
156178
LibGMP.mpq_get_d(mpq)
157179
end
158180

181+
def to_big_f
182+
BigFloat.new { |mpf| LibGMP.mpf_set_q(mpf, mpq) }
183+
end
184+
159185
# Returns the string representing this rational.
160186
#
161187
# Optionally takes a radix base (2 through 36).
@@ -237,6 +263,11 @@ end
237263
struct Float
238264
include Comparable(BigRational)
239265

266+
# Returns a `BigRational` representing this float.
267+
def to_big_r
268+
BigRational.new(self)
269+
end
270+
240271
def <=>(other : BigRational)
241272
-(other <=> self)
242273
end

Diff for: ‎src/big/lib_gmp.cr

+25-3
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,15 @@ lib LibGMP
6161
fun fdiv_r = __gmpz_fdiv_r(rop : MPZ*, op1 : MPZ*, op2 : MPZ*)
6262
fun fdiv_r_ui = __gmpz_fdiv_r_ui(rop : MPZ*, op1 : MPZ*, op2 : ULong)
6363

64+
fun fdiv_qr = __gmpz_fdiv_qr(q : MPZ*, r : MPZ*, n : MPZ*, d : MPZ*)
65+
fun fdiv_qr_ui = __gmpz_fdiv_qr_ui(q : MPZ*, r : MPZ*, n : MPZ*, d : ULong) : ULong
66+
6467
fun tdiv_r = __gmpz_tdiv_r(rop : MPZ*, op1 : MPZ*, op2 : MPZ*)
6568
fun tdiv_r_ui = __gmpz_tdiv_r_ui(rop : MPZ*, op1 : MPZ*, op2 : ULong)
69+
fun tdiv_ui = __gmpz_tdiv_ui(op1 : MPZ*, op2 : ULong) : ULong
70+
71+
fun tdiv_qr = __gmpz_tdiv_qr(q : MPZ*, r : MPZ*, n : MPZ*, d : MPZ*)
72+
fun tdiv_qr_ui = __gmpz_tdiv_qr_ui(q : MPZ*, r : MPZ*, n : MPZ*, d : ULong) : ULong
6673

6774
fun neg = __gmpz_neg(rop : MPZ*, op : MPZ*)
6875
fun abs = __gmpz_abs(rop : MPZ*, op : MPZ*)
@@ -90,6 +97,9 @@ lib LibGMP
9097
fun cmp_ui = __gmpz_cmp_ui(op1 : MPZ*, op2 : ULong) : Int
9198
fun cmp_d = __gmpz_cmp_d(op1 : MPZ*, op2 : Double) : Int
9299

100+
# # Conversion
101+
fun get_d_2exp = __gmpz_get_d_2exp(exp : Long*, op : MPZ*) : Double
102+
93103
# # Number Theoretic Functions
94104

95105
fun gcd = __gmpz_gcd(rop : MPZ*, op1 : MPZ*, op2 : MPZ*)
@@ -143,35 +153,47 @@ lib LibGMP
143153
fun mpf_init2 = __gmpf_init2(x : MPF*, prec : BitcntT)
144154
fun mpf_init_set_d = __gmpf_init_set_d(rop : MPF*, op : Double)
145155
fun mpf_init_set_str = __gmpf_init_set_str(rop : MPF*, str : UInt8*, base : Int) : Int
156+
fun mpf_init_set_ui = __gmpf_init_set_ui(rop : MPF*, op : ULong)
157+
fun mpf_init_set_si = __gmpf_init_set_si(rop : MPF*, op : Long)
146158

147159
# # Precision
148160
fun mpf_set_default_prec = __gmpf_set_default_prec(prec : BitcntT)
149161
fun mpf_get_default_prec = __gmpf_get_default_prec : BitcntT
150162

151-
# # I/O
163+
# # Conversion
152164
fun mpf_get_str = __gmpf_get_str(str : UInt8*, expptr : MpExp*, base : Int, n_digits : LibC::SizeT, op : MPF*) : UInt8*
153165
fun mpf_get_d = __gmpf_get_d(op : MPF*) : Double
154166
fun mpf_set_d = __gmpf_set_d(op : MPF*, op : Double)
167+
fun mpf_set = __gmpf_set(op : MPF*, op : MPF*)
168+
fun mpf_set_z = __gmpf_set_z(rop : MPF*, op : MPZ*)
169+
fun mpf_set_q = __gmpf_set_q(rop : MPF*, op : MPQ*)
155170
fun mpf_get_si = __gmpf_get_si(op : MPF*) : Long
156171
fun mpf_get_ui = __gmpf_get_ui(op : MPF*) : ULong
157-
fun mpf_ceil = __gmpf_ceil(rop : MPF*, op : MPF*)
158-
fun mpf_floor = __gmpf_floor(rop : MPF*, op : MPF*)
172+
fun mpf_get_d_2exp = __gmpf_get_d_2exp(exp : Long*, op : MPF*) : Double
159173

160174
# # Arithmetic
161175
fun mpf_add = __gmpf_add(rop : MPF*, op1 : MPF*, op2 : MPF*)
162176
fun mpf_sub = __gmpf_sub(rop : MPF*, op1 : MPF*, op2 : MPF*)
163177
fun mpf_mul = __gmpf_mul(rop : MPF*, op1 : MPF*, op2 : MPF*)
164178
fun mpf_div = __gmpf_div(rop : MPF*, op1 : MPF*, op2 : MPF*)
179+
fun mpf_div_ui = __gmpf_div_ui(rop : MPF*, op1 : MPF*, op2 : ULong)
165180
fun mpf_neg = __gmpf_neg(rop : MPF*, op : MPF*)
166181
fun mpf_abs = __gmpf_abs(rop : MPF*, op : MPF*)
167182
fun mpf_pow_ui = __gmpf_pow_ui(rop : MPF*, op1 : MPF*, op2 : ULong)
183+
fun mpf_mul_2exp = __gmpf_mul_2exp(rop : MPF*, op1 : MPF*, op2 : BitcntT)
184+
fun mpf_div_2exp = __gmpf_div_2exp(rop : MPF*, op1 : MPF*, op2 : BitcntT)
168185

169186
# # Comparison
170187
fun mpf_cmp = __gmpf_cmp(op1 : MPF*, op2 : MPF*) : Int
171188
fun mpf_cmp_d = __gmpf_cmp_d(op1 : MPF*, op2 : Double) : Int
172189
fun mpf_cmp_ui = __gmpf_cmp_ui(op1 : MPF*, op2 : ULong) : Int
173190
fun mpf_cmp_si = __gmpf_cmp_si(op1 : MPF*, op2 : Long) : Int
191+
fun mpf_cmp_z = __gmpf_cmp_z(op1 : MPF*, op2 : MPZ*) : Int
174192

193+
# # Miscellaneous
194+
fun mpf_ceil = __gmpf_ceil(rop : MPF*, op : MPF*)
195+
fun mpf_floor = __gmpf_floor(rop : MPF*, op : MPF*)
196+
fun mpf_trunc = __gmpf_trunc(rop : MPF*, op : MPF*)
175197
fun mpf_integer_p = __gmpf_integer_p(op : MPF*) : Int
176198

177199
# # Memory

0 commit comments

Comments
 (0)
Please sign in to comment.