1use crate::common::consts::ONE;
4use crate::common::consts::TEN;
5use crate::common::consts::TWO;
6use crate::common::util::calc_add_cost;
7use crate::common::util::calc_mul_cost;
8use crate::common::util::calc_sqrt_cost;
9use crate::common::util::count_leading_ones;
10use crate::common::util::count_leading_zeroes_skip_first;
11use crate::common::util::round_p;
12use crate::defs::Error;
13use crate::defs::RoundingMode;
14use crate::defs::Sign;
15use crate::num::BigFloatNumber;
16use crate::ops::consts::Consts;
17use crate::ops::series::series_cost_optimize;
18use crate::ops::series::series_run;
19use crate::ops::series::ArgReductionEstimator;
20use crate::ops::series::PolycoeffGen;
21use crate::Exponent;
22use crate::WORD_BIT_SIZE;
23
24struct AtanhPolycoeffGen {
26 acc: BigFloatNumber,
27 one_full_p: BigFloatNumber,
28 val: BigFloatNumber,
29 iter_cost: usize,
30}
31
32impl AtanhPolycoeffGen {
33 fn new(p: usize) -> Result<Self, Error> {
34 let acc = BigFloatNumber::from_word(1, 1)?;
35 let one_full_p = BigFloatNumber::from_word(1, p)?;
36 let val = BigFloatNumber::from_word(1, p)?;
37
38 let iter_cost = calc_add_cost(p) + calc_add_cost(acc.mantissa_max_bit_len());
39
40 Ok(AtanhPolycoeffGen {
41 acc,
42 one_full_p,
43 val,
44 iter_cost,
45 })
46 }
47}
48
49impl PolycoeffGen for AtanhPolycoeffGen {
50 fn next(&mut self, rm: RoundingMode) -> Result<&BigFloatNumber, Error> {
51 self.acc = self.acc.add(&TWO, self.acc.mantissa_max_bit_len(), rm)?;
52 self.val = self
53 .one_full_p
54 .div(&self.acc, self.one_full_p.mantissa_max_bit_len(), rm)?;
55
56 Ok(&self.val)
57 }
58
59 #[inline]
60 fn iter_cost(&self) -> usize {
61 self.iter_cost
62 }
63}
64
65struct LnArgReductionEstimator {}
66
67impl ArgReductionEstimator for LnArgReductionEstimator {
68 fn reduction_cost(n: usize, p: usize) -> u64 {
70 let cost_mul = calc_mul_cost(p);
72 let cost_add = calc_add_cost(p);
73 let sqrt_cost = calc_sqrt_cost(p, cost_mul, cost_add);
74
75 n as u64 * sqrt_cost as u64
76 }
77
78 #[inline]
80 fn reduction_effect(n: usize, m: isize) -> usize {
81 (m + n as isize) as usize
82 }
83}
84
85impl BigFloatNumber {
86 pub fn ln(&self, p: usize, rm: RoundingMode, cc: &mut Consts) -> Result<Self, Error> {
95 let p = round_p(p);
96
97 if self.is_zero() || self.is_negative() {
103 return Err(Error::InvalidArgument);
104 }
105
106 let mut m = self.clone()?;
107 let e = m.normalize2() as isize;
108 let e = self.exponent() as isize - e;
109
110 m.set_exponent(0);
111
112 let additional_prec = if e == 0 {
114 count_leading_ones(m.mantissa().digits())
115 } else if e == 1 {
116 count_leading_zeroes_skip_first(m.mantissa().digits())
117 } else {
118 0
119 } + 5; if e == 1 && additional_prec == m.mantissa_max_bit_len() + 5 {
123 return Self::new2(p, Sign::Pos, self.inexact());
124 }
125
126 let mut p_inc = WORD_BIT_SIZE;
127 let mut p_wrk = p.max(self.mantissa_max_bit_len()) + p_inc;
128
129 loop {
130 let mut x = m.clone()?;
131
132 let p_x = p_wrk + additional_prec;
133 x.set_precision(p_x, RoundingMode::None)?;
134
135 let p1 = Self::ln_series(x, RoundingMode::None)?;
136
137 let mut ret = if e == 0 {
138 p1
139 } else {
140 let p2 = cc.ln_2_num(p1.mantissa_max_bit_len(), RoundingMode::None)?;
141
142 let mut n = Self::from_usize(e.unsigned_abs())?;
143 if e < 0 {
144 n.set_sign(Sign::Neg);
145 }
146
147 let p2n = p2.mul(&n, p1.mantissa_max_bit_len(), RoundingMode::None)?;
148 p1.add(&p2n, p1.mantissa_max_bit_len(), RoundingMode::None)?
149 };
150
151 if ret.try_set_precision(p, rm, p_wrk)? {
152 ret.set_inexact(ret.inexact() | self.inexact());
153 return Ok(ret);
154 }
155
156 p_wrk += p_inc;
157 p_inc = round_p(p_wrk / 5);
158 }
159 }
160
161 fn ln_series(mut x: Self, rm: RoundingMode) -> Result<Self, Error> {
162 let p = x.mantissa_max_bit_len();
163 let mut polycoeff_gen = AtanhPolycoeffGen::new(p)?;
164 let (mut reduction_times, niter, e_eff) =
165 series_cost_optimize::<LnArgReductionEstimator>(p, &polycoeff_gen, 0, 2, false);
166
167 if e_eff < 3 {
169 reduction_times += 3 - e_eff;
170 }
171
172 let add_prec = 7 - e_eff as isize;
176 let p_arg = p + if add_prec > 0 { add_prec as usize } else { 5 };
177 x.set_precision(p_arg, rm)?;
178
179 let arg = if reduction_times > 0 {
180 Self::ln_arg_reduce(x, reduction_times, rm)?
181 } else {
182 x
183 };
184
185 let x1 = arg.sub(&ONE, p, rm)?;
187 let x2 = arg.add(&ONE, p, rm)?;
188 let z = x1.div(&x2, p, rm)?;
189
190 let x_step = z.mul(&z, p, rm)?; let x_first = z.mul(&x_step, p, rm)?; let ret = series_run(z, x_first, x_step, niter, &mut polycoeff_gen)?;
194
195 Self::ln_arg_restore(ret, reduction_times + 1)
196 }
197
198 fn ln_arg_reduce(mut x: Self, n: usize, _rm: RoundingMode) -> Result<Self, Error> {
200 for _ in 0..n {
201 x = x.sqrt(x.mantissa_max_bit_len(), RoundingMode::Up)?;
202 }
203
204 Ok(x)
205 }
206
207 fn ln_arg_restore(mut x: Self, n: usize) -> Result<Self, Error> {
209 x.set_exponent(x.exponent() + n as Exponent);
210
211 Ok(x)
212 }
213
214 pub fn log2(&self, p: usize, rm: RoundingMode, cc: &mut Consts) -> Result<Self, Error> {
223 let p = round_p(p);
224
225 if self.is_zero() || self.is_negative() {
228 return Err(Error::InvalidArgument);
229 }
230
231 let mut m = self.clone()?;
232 let e = m.normalize2() as isize;
233 let e = self.exponent() as isize - e;
234
235 m.set_exponent(0);
236
237 let zeroes_cnt = count_leading_zeroes_skip_first(m.mantissa().digits());
238 if zeroes_cnt == m.mantissa_max_bit_len() {
239 let mut ret = Self::from_usize((e - 1).unsigned_abs())?;
241
242 if e < 1 {
243 ret.set_sign(Sign::Neg);
244 }
245
246 ret.set_precision(p, rm)?;
247 ret.set_inexact(m.inexact());
248
249 return Ok(ret);
250 }
251
252 let additional_prec = if e == 0 {
253 count_leading_ones(m.mantissa().digits())
254 } else if e == 1 {
255 zeroes_cnt
256 } else {
257 0
258 } + 5; let mut p_inc = WORD_BIT_SIZE;
261 let mut p_wrk = p.max(self.mantissa_max_bit_len()) + p_inc;
262
263 loop {
264 let mut x = m.clone()?;
265 x.set_inexact(false);
266
267 let p_x = p_wrk + additional_prec;
268 x.set_precision(p_x, RoundingMode::None)?;
269
270 let p1 = Self::ln_series(x, RoundingMode::None)?;
271
272 let p2 = cc.ln_2_num(p_x, RoundingMode::None)?;
273
274 let p3 = p1.div(&p2, p_x, RoundingMode::None)?;
275
276 let mut n = Self::from_usize(e.unsigned_abs())?;
277 if e < 0 {
278 n.set_sign(Sign::Neg);
279 }
280
281 let mut ret = p3.add(&n, p_x, RoundingMode::None)?;
282
283 if ret.try_set_precision(p, rm, p_wrk)? {
284 ret.set_inexact(ret.inexact() | self.inexact());
285 return Ok(ret);
286 }
287
288 p_wrk += p_inc;
289 p_inc = round_p(p_wrk / 5);
290 }
291 }
292
293 pub fn log10(&self, p: usize, rm: RoundingMode, cc: &mut Consts) -> Result<Self, Error> {
302 let p = round_p(p);
303
304 let mut p_inc = WORD_BIT_SIZE;
307 let mut p_wrk = p.max(self.mantissa_max_bit_len()) + p_inc;
308
309 let mut x = self.clone()?;
310 x.set_inexact(false);
311
312 loop {
313 let p_x = p_wrk + 5; x.set_precision(p_x, RoundingMode::None)?;
315
316 let p1 = x.ln(p_x, RoundingMode::None, cc)?;
317
318 let p2 = cc.ln_10_num(p_x, RoundingMode::None)?;
319
320 let mut ret = p1.div(&p2, p_x, RoundingMode::None)?;
321
322 if ret.is_int() {
324 let n = ret.int_as_usize()?;
325
326 let tp = TEN.powi(n, p_x, RoundingMode::None)?;
327
328 if tp.cmp(&x) == 0 {
329 ret.set_precision(p, rm)?;
330 return Ok(ret);
331 }
332 }
333
334 if ret.try_set_precision(p, rm, p_wrk)? {
335 ret.set_inexact(ret.inexact() | self.inexact());
336 return Ok(ret);
337 }
338
339 p_wrk += p_inc;
340 p_inc = round_p(p_wrk / 5);
341 }
342 }
343
344 pub fn log(
354 &self,
355 n: &Self,
356 p: usize,
357 rm: RoundingMode,
358 cc: &mut Consts,
359 ) -> Result<Self, Error> {
360 let p = round_p(p);
361
362 if self.is_zero() || self.is_negative() || n.is_zero() || n.is_negative() {
363 return Err(Error::InvalidArgument);
364 }
365
366 let mut p_inc = WORD_BIT_SIZE;
369 let mut p_wrk = p.max(self.mantissa_max_bit_len().max(n.mantissa_max_bit_len())) + p_inc;
370
371 let mut x = self.clone()?;
372 let mut y = n.clone()?;
373 x.set_inexact(false);
374 y.set_inexact(false);
375
376 loop {
377 let p_x = p_wrk + 5;
378 x.set_precision(p_x, RoundingMode::None)?;
379 y.set_precision(p_x, RoundingMode::None)?;
380
381 let p1 = x.ln(p_x, RoundingMode::None, cc)?;
382
383 let p2 = y.ln(p_x, RoundingMode::None, cc)?;
384
385 let mut ret = p1.div(&p2, p_x, RoundingMode::None)?;
386
387 let mut ret2 = ret.clone()?; if ret.try_set_precision(p, rm, p_wrk)? {
389 ret.set_inexact(ret.inexact() | self.inexact() | n.inexact());
390 return Ok(ret);
391 } else {
392 let pwr = y.pow(
394 &ret2,
395 p_x.max(self.mantissa_max_bit_len()),
396 RoundingMode::None,
397 cc,
398 )?;
399
400 if pwr.cmp(self) == 0 {
401 ret2.set_inexact(ret2.inexact() | self.inexact() | n.inexact());
402 ret2.set_precision(p, rm)?;
403 return Ok(ret2);
404 }
405 }
406
407 p_wrk += p_inc;
408 p_inc = round_p(p_wrk / 5);
409 }
410 }
411}
412
413#[cfg(test)]
414mod tests {
415
416 use crate::{
417 common::{
418 consts::TEN,
419 util::{log2_ceil, random_subnormal},
420 },
421 WORD_BIT_SIZE,
422 };
423
424 use super::*;
425
426 #[cfg(not(feature = "std"))]
427 use alloc::vec::Vec;
428
429 #[test]
430 fn test_logarithm() {
431 let mut cc = Consts::new().unwrap();
432
433 let rm = RoundingMode::ToEven;
434 let p = 320;
443 let d1 = BigFloatNumber::parse(
444 "F.FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2DC85F7E77EC4872DC85F7E77EC487_e-1",
445 crate::Radix::Hex,
446 p,
447 RoundingMode::None,
448 &mut cc,
449 )
450 .unwrap();
451 let d2 = d1.ln(p, RoundingMode::ToEven, &mut cc).unwrap();
452 let d3 = BigFloatNumber::parse("-D.237A0818813B78D237A0818813B7900000000000000000000564FA7B56FC57E9FBF3EE86C58F3F4_e-33", crate::Radix::Hex, p, RoundingMode::None, &mut cc).unwrap();
453
454 assert!(d2.cmp(&d3) == 0);
457
458 let d1 = BigFloatNumber::parse(
459 "1.00000000000000000000000000000000000000000000000000000000000000002DC85F7E77EC487C",
460 crate::Radix::Hex,
461 p,
462 RoundingMode::None,
463 &mut cc,
464 )
465 .unwrap();
466 let d2 = d1.ln(p, RoundingMode::ToEven, &mut cc).unwrap();
467 let d3 = BigFloatNumber::parse("2.DC85F7E77EC487BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE7F8CC184E38EBC_e-41", crate::Radix::Hex, p, RoundingMode::None, &mut cc).unwrap();
468
469 assert!(d2.cmp(&d3) == 0);
472
473 let prec = 3200;
475 let mut eps = ONE.clone().unwrap();
476
477 let d1 = BigFloatNumber::max_value(prec).unwrap();
478 let d2 = d1.ln(prec, RoundingMode::Down, &mut cc).unwrap();
479 let d3 = d2.exp(prec, RoundingMode::Down, &mut cc).unwrap();
480 eps.set_exponent(
481 d1.exponent() - prec as Exponent
482 + 1
483 + log2_ceil(d1.exponent().unsigned_abs() as usize) as Exponent,
484 );
485
486 assert!(
487 d1.sub(&d3, prec, RoundingMode::ToEven)
488 .unwrap()
489 .abs()
490 .unwrap()
491 .cmp(&eps)
492 < 0
493 );
494
495 let d2 = d1.log2(prec, RoundingMode::ToEven, &mut cc).unwrap();
496 match TWO.pow(&d2, prec, RoundingMode::ToEven, &mut cc) {
497 Ok(d3) => {
498 eps.set_exponent(
499 d1.exponent() - prec as Exponent
500 + log2_ceil(d1.exponent().unsigned_abs() as usize) as Exponent,
501 );
502
503 assert!(
504 d1.sub(&d3, prec, RoundingMode::ToEven)
505 .unwrap()
506 .abs()
507 .unwrap()
508 .cmp(&eps)
509 < 0
510 );
511 }
512 Err(e) => {
513 if e != Error::ExponentOverflow(Sign::Pos) {
514 panic!("unexpected error");
515 }
516 }
517 }
518
519 let d2 = d1.log10(prec, RoundingMode::ToEven, &mut cc).unwrap();
520 match TEN.pow(&d2, prec, RoundingMode::ToEven, &mut cc) {
521 Ok(d3) => {
522 eps.set_exponent(
523 d1.exponent() - prec as Exponent
524 + log2_ceil(d1.exponent().unsigned_abs() as usize) as Exponent,
525 );
526
527 assert!(
528 d1.sub(&d3, prec, RoundingMode::ToEven)
529 .unwrap()
530 .abs()
531 .unwrap()
532 .cmp(&eps)
533 < 0
534 );
535 }
536 Err(e) => {
537 if e != Error::ExponentOverflow(Sign::Pos) {
538 panic!("unexpected error");
539 }
540 }
541 }
542
543 let d1 = BigFloatNumber::min_positive(prec).unwrap();
545 let d2 = d1.ln(prec, RoundingMode::ToEven, &mut cc).unwrap();
546 let d3 = d2.exp(prec, RoundingMode::ToEven, &mut cc).unwrap();
547 let eps = BigFloatNumber::min_positive_normal(prec).unwrap();
548
549 assert!(
550 d1.sub(&d3, prec, RoundingMode::ToEven)
551 .unwrap()
552 .abs()
553 .unwrap()
554 .cmp(&eps)
555 <= 0
556 );
557
558 let mut eps = ONE.clone().unwrap();
560 for _ in 0..1000 {
561 let prec = (rand::random::<usize>() % 3 + 3) * WORD_BIT_SIZE;
562
563 let mut d1 = random_subnormal(prec);
564 d1.set_sign(Sign::Pos);
565 let mut d2 = d1.ln(prec, RoundingMode::ToEven, &mut cc).unwrap();
566 let d2e = d2.exponent();
567 d2.set_exponent(d2e / 2 + (d2e & 1));
568 let d3 = d2.exp(prec + 1, RoundingMode::None, &mut cc).unwrap();
569 let d4 = d3.powi(1 << (d2e / 2), prec, RoundingMode::ToEven).unwrap();
570
571 eps.set_exponent(d2e - prec as Exponent);
572 let err = eps.exp(prec, RoundingMode::Up, &mut cc).unwrap();
573
574 assert!(d1.cmp(&d4.mul(&err, prec, RoundingMode::Up).unwrap()) <= 0);
580 assert!(d1.cmp(&d4.div(&err, prec, RoundingMode::Down).unwrap()) >= 0);
581 }
582
583 let d1 = BigFloatNumber::min_positive(prec).unwrap();
584 let d2 = d1.log2(prec, RoundingMode::ToEven, &mut cc).unwrap();
585 let d3 = TWO.pow(&d2, prec, RoundingMode::ToEven, &mut cc).unwrap();
586 let eps = BigFloatNumber::min_positive_normal(prec).unwrap();
587
588 assert!(
589 d1.sub(&d3, prec, RoundingMode::ToEven)
590 .unwrap()
591 .abs()
592 .unwrap()
593 .cmp(&eps)
594 <= 0
595 );
596
597 let d1 = BigFloatNumber::min_positive(prec).unwrap();
598 let d2 = d1.log10(prec, RoundingMode::ToEven, &mut cc).unwrap();
599 let d3 = TEN.pow(&d2, prec, RoundingMode::ToEven, &mut cc).unwrap();
600 let eps = BigFloatNumber::min_positive_normal(prec).unwrap();
601
602 assert!(
603 d1.sub(&d3, prec, RoundingMode::ToEven)
604 .unwrap()
605 .abs()
606 .unwrap()
607 .cmp(&eps)
608 <= 0
609 );
610
611 assert!(TWO.log(&ONE, p, rm, &mut cc).unwrap_err() == Error::DivisionByZero);
613
614 let d1 = BigFloatNumber::min_positive(prec).unwrap();
615 let d2 = BigFloatNumber::max_value(prec).unwrap();
616
617 assert!(d1.log(&d1, prec, rm, &mut cc).unwrap().cmp(&ONE) == 0);
618 assert!(d2.log(&d2, prec, rm, &mut cc).unwrap().cmp(&ONE) == 0);
619 assert!(d1.log(&d2, prec, rm, &mut cc).is_ok());
620 assert!(d2.log(&d1, prec, rm, &mut cc).is_ok());
621
622 let mut nums = Vec::new();
624 for s in [
625 "1.23456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF12_e-100000",
626 "0.FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF123456789ABCDEF0123456789ABCDEF12_e+0",
627 "1.0000000000000000000000000000000123456789ABCDEF0123456789ABCDEF12_e+0",
628 "1.23456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF12_e+100000",
629 "1.23456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF12_e+1000",
630 "1.23456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF12_e-1000",
631 ] {
632 nums.push(
633 BigFloatNumber::parse(s, crate::Radix::Hex, 256, RoundingMode::None, &mut cc)
634 .unwrap(),
635 );
636 }
637
638 let mediumsmall = nums.pop().unwrap();
639 let mediumlarge = nums.pop().unwrap();
640 let large = nums.pop().unwrap();
641 let above1 = nums.pop().unwrap();
642 let below1 = nums.pop().unwrap();
643 let small = nums.pop().unwrap();
644
645 let s = "1.010101110001000100000101000110000000101010001001001111001011001001110000010000010010001101010111001111111000100110100110101001101111010011000110111101011100010000100111001110000111100110011011111100001111100011001110011110001001111111110000100101001110001e-10010010";
647 let refn =
648 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
649 let d1 = below1
650 .log(&small, 256, RoundingMode::ToEven, &mut cc)
651 .unwrap();
652 assert!(d1.cmp(&refn) == 0);
653
654 let s = "-1.10100100001101110010010011011100100001110110010010111001011000010000000000010101000100100011101000011010111010110000011111001101111011110100010100101111100110110111101100111100010011000100101011101111100001110011100001111101101110011000001001100010101101e-10010110";
655 let refn =
656 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
657 let d1 = above1
658 .log(&small, 256, RoundingMode::ToEven, &mut cc)
659 .unwrap();
660 assert!(d1.cmp(&refn) == 0);
661
662 let s = "-1.000000000000000000000001011111010110000001001010100010010000111110010100111100100000000111110011101100111000000010001001011010001110100011001001111010101111000111010010000011000110011011011101101001001010011011010111011011010001110100000010100100001001001e+0";
663 let refn =
664 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
665 let d1 = large
666 .log(&small, 256, RoundingMode::ToEven, &mut cc)
667 .unwrap();
668 assert!(d1.cmp(&refn) == 0);
669
670 let s = "1.111111111111111010000100000111010001010111000001011110010111101010100010111100000000111001000000001100101111011100100000100000000001111011011110111110010001111111000101101001011000100100111000111111011100111101101010010100000001101001110001111111110100101e-1001";
671 let refn =
672 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
673 let d1 = mediumsmall
674 .log(&small, 256, RoundingMode::ToEven, &mut cc)
675 .unwrap();
676 assert!(d1.cmp(&refn) == 0);
677
678 let s = "-1.00000000000000001011111101101110110101010110100111001100010100100100001101111001111110101101001110011010000001001111100100101000110110010101101001101110011000011110111100111001101000100100000100100101101111110010001001000101000011111100100110010000111011e-1000";
679 let refn =
680 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
681 let d1 = mediumlarge
682 .log(&small, 256, RoundingMode::ToEven, &mut cc)
683 .unwrap();
684 assert!(d1.cmp(&refn) == 0);
685
686 let s = "1.01111110000011110101111111010000100100110001110110101100011100010101010010001100000100011011011100010111000011100111111010100000010001001111111000010111001000011000011110001110011001001011010101111111100110001000000011011111101111001110100010010101001101e+10010001";
688 let refn =
689 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
690 let d1 = small
691 .log(&below1, 256, RoundingMode::ToEven, &mut cc)
692 .unwrap();
693 assert!(d1.cmp(&refn) == 0);
694
695 let s = "-1.001110011001000111000010110000011000011111110110001100100011010101110000000001101101100001100011010000011001111101001101000010001001100010000001111001011000000000111110110101101111010100100000001001100110111110111010000000001000000011100100110110001001011e-100";
696 let refn =
697 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
698 let d1 = above1
699 .log(&below1, 256, RoundingMode::ToEven, &mut cc)
700 .unwrap();
701 assert!(d1.cmp(&refn) == 0);
702
703 let s = "-1.01111110000011110110001000001001101111111011010001000110110010011010110010100010101010100110101010110000000101100010011000110001000111001100010011010011010111101011101010110100001110101100100000111001110011010011001101001001000001100100110010000001111101e+10010001";
704 let refn =
705 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
706 let d1 = large
707 .log(&below1, 256, RoundingMode::ToEven, &mut cc)
708 .unwrap();
709 assert!(d1.cmp(&refn) == 0);
710
711 let s = "1.011111100000111001000100010101101101111000011011110011010111000101110101010010110000010001000100010111111011111010001001111111001100110110000011010101101010011010001110001101100100011001100001110000100101100110100101011011111010111110100100001011000001e+10001001";
712 let refn =
713 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
714 let d1 = mediumsmall
715 .log(&below1, 256, RoundingMode::ToEven, &mut cc)
716 .unwrap();
717 assert!(d1.cmp(&refn) == 0);
718
719 let s = "-1.0111111000010000011111011000001101110100101101100010010111001001100010111110001110110111110111010110011101100110000110101101010010010100001111111001001111011001101101000000110001011001000110111111011100001100000011101011100100010011100100001110101100011e+10001001";
720 let refn =
721 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
722 let d1 = mediumlarge
723 .log(&below1, 256, RoundingMode::ToEven, &mut cc)
724 .unwrap();
725 assert!(d1.cmp(&refn) == 0);
726
727 let s = "-1.00110111111010101000110100111001010010000001101100111011000000110101010011010001010111010110001010110010000101110100010001010101011011100101100101010101001111110010011110001010100010110111110010010011001111000000001100110011010101100000010101101010001e+10010101";
729 let refn =
730 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
731 let d1 = small
732 .log(&above1, 256, RoundingMode::ToEven, &mut cc)
733 .unwrap();
734 assert!(d1.cmp(&refn) == 0);
735
736 let s = "-1.10100010000000000000000000000000000000000000000000000001101001011110000000000000000000000000000000000000000000011000110100011010111000101101110000000000000000000000000101110101101111010011101001011100100000000000000000000001010111111011111010110100000101e+11";
737 let refn =
738 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
739 let d1 = below1
740 .log(&above1, 256, RoundingMode::ToEven, &mut cc)
741 .unwrap();
742 assert!(d1.cmp(&refn) == 0);
743
744 let s = "1.0011011111101010100011110000100111110101100000100010111100000101011101001011110110100101000010010111111101011110010100010100110111000101010110100111101001011111010000011001111000001010110011011001011101101111111100010111101010100011001010100000001001001e+10010101";
745 let refn =
746 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
747 let d1 = large
748 .log(&above1, 256, RoundingMode::ToEven, &mut cc)
749 .unwrap();
750 assert!(d1.cmp(&refn) == 0);
751
752 let s = "-1.001101111110100110100101110010101110101101010100101100111111010001101110101000111010110111001111011101010011010001001110101001100001100101000111010101111100001000101010110101001010001010100010111110110101111011010110101100000110101001001011101000100100111e+10001101";
753 let refn =
754 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
755 let d1 = mediumsmall
756 .log(&above1, 256, RoundingMode::ToEven, &mut cc)
757 .unwrap();
758 assert!(d1.cmp(&refn) == 0);
759
760 let s = "1.00110111111010110111011001111000010100100100100010110110000101000101101011101011010101001001110010111100010000010100011011111101000110100110110001110111110111000011111001010011111100111010011100101111010011010001110111111101100011101110001111001010000111e+10001101";
761 let refn =
762 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
763 let d1 = mediumlarge
764 .log(&above1, 256, RoundingMode::ToEven, &mut cc)
765 .unwrap();
766 assert!(d1.cmp(&refn) == 0);
767
768 let s = "-1.111111111111111111111101000001010011111101101111010111100011000001010011101001110001010000100011001101110111010000110100011100111000001001101110000001111000000100110110110001001101001110101000000101010111111000100101110100000111101010010101000110001001001e-1";
770 let refn =
771 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
772 let d1 = small
773 .log(&large, 256, RoundingMode::ToEven, &mut cc)
774 .unwrap();
775 assert!(d1.cmp(&refn) == 0);
776
777 let s = "-1.010101110001000100000011000110001111010100101101010111001100110001001110010101000111010100110100100101010000101011110011001001010101000101110000001101010100011001100111100000000111111110100000001111010111001101000101100101111010110011111001011000101110001e-10010010";
778 let refn =
779 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
780 let d1 = below1
781 .log(&large, 256, RoundingMode::ToEven, &mut cc)
782 .unwrap();
783 assert!(d1.cmp(&refn) == 0);
784
785 let s = "1.1010010000110111001000100110101010000011010001110111101100001000101001011000101100010001110101111001111110100010100101100110011110011111001101110001000111011101100101101011001001000100111111011101100010100010111110100000101100010010000100000000111100001e-10010110";
786 let refn =
787 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
788 let d1 = above1
789 .log(&large, 256, RoundingMode::ToEven, &mut cc)
790 .unwrap();
791 assert!(d1.cmp(&refn) == 0);
792
793 let s = "-1.111111111111111010000001001000100101011101100110110001110100000111111101010111011001101110101101010101011101010001010011111110101111100000111010110001000101101111111101110011000011110111011110110010011101000111111011001001011000011111010110110101010101011e-1001";
794 let refn =
795 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
796 let d1 = mediumsmall
797 .log(&large, 256, RoundingMode::ToEven, &mut cc)
798 .unwrap();
799 assert!(d1.cmp(&refn) == 0);
800
801 let s = "1.000000000000000010111101111100010111010000000100010010110111011100101011001001001011110000111010111100001100111111110000001111000100010100011001101000011001001010011100011111000100101011100100101001011101011000010101010101010111100101011111001000011001111e-1000";
802 let refn =
803 BigFloatNumber::parse(s, crate::Radix::Bin, 256, RoundingMode::None, &mut cc).unwrap();
804 let d1 = mediumlarge
805 .log(&large, 256, RoundingMode::ToEven, &mut cc)
806 .unwrap();
807 assert!(d1.cmp(&refn) == 0);
808 }
809
810 #[ignore]
811 #[test]
812 #[cfg(feature = "std")]
813 fn ln_perf() {
814 let mut cc = Consts::new().unwrap();
815 let mut n = vec![];
816 let p = 133;
817 for _ in 0..10000 {
818 let mut nn = BigFloatNumber::random_normal(p, -100, 100).unwrap();
819 nn.set_sign(Sign::Pos);
820 n.push(nn);
821 }
822
823 for _ in 0..5 {
824 let start_time = std::time::Instant::now();
825 for ni in n.iter() {
826 let _f = ni.ln(p, RoundingMode::ToEven, &mut cc).unwrap();
827 }
828 let time = start_time.elapsed();
829 println!("{}", time.as_millis());
830 }
831 }
832}