injective_math/fp_decimal/
log.rs1use crate::fp_decimal::error::FPDecimalError;
2use crate::fp_decimal::{FPDecimal, U256};
4
5impl FPDecimal {
6 pub(crate) fn log_e(self) -> Option<FPDecimal> {
7 let e = FPDecimal::E;
8 if self == FPDecimal::ONE {
9 return Some(FPDecimal::ZERO);
10 }
11 if self == FPDecimal::E {
12 return Some(FPDecimal::ONE);
13 }
14 if self == e * e {
15 return Some(FPDecimal::TWO);
16 }
17 if self == e * e * e {
18 return Some(FPDecimal::THREE);
19 }
20 if self == e * e * e * e {
21 return Some(FPDecimal::FOUR);
22 }
23 if self == e * e * e * e * e {
24 return Some(FPDecimal::FIVE);
25 }
26 if self == e * e * e * e * e * e {
27 return Some(FPDecimal::SIX);
28 }
29 if self == e * e * e * e * e * e * e {
30 return Some(FPDecimal::SEVEN);
31 }
32 if self == e * e * e * e * e * e * e * e {
33 return Some(FPDecimal::EIGHT);
34 }
35 if self == e * e * e * e * e * e * e * e * e {
36 return Some(FPDecimal::NINE);
37 }
38 if self == e * e * e * e * e * e * e * e * e * e {
39 return Some(FPDecimal::TEN);
40 }
41 if self == e * e * e * e * e * e * e * e * e * e * e {
42 return Some(FPDecimal::ELEVEN);
43 }
44
45 if self == FPDecimal::ONE / FPDecimal::E {
46 return Some(-FPDecimal::ONE);
47 }
48 if self == FPDecimal::ONE / (e * e) {
49 return Some(-FPDecimal::TWO);
50 }
51 if self == FPDecimal::ONE / (e * e * e) {
52 return Some(-FPDecimal::THREE);
53 }
54 if self == FPDecimal::ONE / (e * e * e * e) {
55 return Some(-FPDecimal::FOUR);
56 }
57 if self == FPDecimal::ONE / (e * e * e * e * e) {
58 return Some(-FPDecimal::FIVE);
59 }
60 if self == FPDecimal::ONE / (e * e * e * e * e * e) {
61 return Some(-FPDecimal::SIX);
62 }
63 if self == FPDecimal::ONE / (e * e * e * e * e * e * e) {
64 return Some(-FPDecimal::SEVEN);
65 }
66 if self == FPDecimal::ONE / (e * e * e * e * e * e * e * e) {
67 return Some(-FPDecimal::EIGHT);
68 }
69 if self == FPDecimal::ONE / (e * e * e * e * e * e * e * e * e) {
70 return Some(-FPDecimal::NINE);
71 }
72 if self == FPDecimal::ONE / (e * e * e * e * e * e * e * e * e * e) {
73 return Some(-FPDecimal::TEN);
74 }
75 if self == FPDecimal::ONE / (e * e * e * e * e * e * e * e * e * e * e) {
76 return Some(-FPDecimal::ELEVEN);
77 }
78 None
79 }
80
81 pub(crate) fn log2(self) -> Option<FPDecimal> {
82 if self == FPDecimal::ONE {
83 return Some(FPDecimal::ZERO);
84 }
85 if self == FPDecimal::TWO {
86 return Some(FPDecimal::ONE);
87 }
88 if self == FPDecimal::FOUR {
89 return Some(FPDecimal::TWO);
90 }
91 if self == FPDecimal::EIGHT {
92 return Some(FPDecimal::THREE);
93 }
94 if self == FPDecimal::from(16u128) {
95 return Some(FPDecimal::FOUR);
96 }
97 if self == FPDecimal::from(32u128) {
98 return Some(FPDecimal::FIVE);
99 }
100 if self == FPDecimal::from(64u128) {
101 return Some(FPDecimal::SIX);
102 }
103 if self == FPDecimal::from(128u128) {
104 return Some(FPDecimal::SEVEN);
105 }
106 if self == FPDecimal::from(256u128) {
107 return Some(FPDecimal::EIGHT);
108 }
109 if self == FPDecimal::from(512u128) {
110 return Some(FPDecimal::NINE);
111 }
112 if self == FPDecimal::from(1024u128) {
113 return Some(FPDecimal::TEN);
114 }
115 if self == FPDecimal::from(2048u128) {
116 return Some(FPDecimal::ELEVEN);
117 }
118 if self == FPDecimal::from(4096u128) {
119 return Some(FPDecimal::from(12u128));
120 }
121 if self == FPDecimal::from(8192u128) {
122 return Some(FPDecimal::from(13u128));
123 }
124 if self == FPDecimal::from(16384u128) {
125 return Some(FPDecimal::from(14u128));
126 }
127 if self == FPDecimal::from(32768u128) {
128 return Some(FPDecimal::from(15u128));
129 }
130
131 if self == FPDecimal::ONE / FPDecimal::TWO {
132 return Some(-FPDecimal::ONE);
133 }
134 if self == FPDecimal::ONE / FPDecimal::FOUR {
135 return Some(-FPDecimal::TWO);
136 }
137 if self == FPDecimal::ONE / FPDecimal::EIGHT {
138 return Some(-FPDecimal::THREE);
139 }
140 if self == FPDecimal::ONE / FPDecimal::from(16u128) {
141 return Some(-FPDecimal::FOUR);
142 }
143 if self == FPDecimal::ONE / FPDecimal::from(32u128) {
144 return Some(-FPDecimal::FIVE);
145 }
146 if self == FPDecimal::ONE / FPDecimal::from(64u128) {
147 return Some(-FPDecimal::SIX);
148 }
149 if self == FPDecimal::ONE / FPDecimal::from(128u128) {
150 return Some(-FPDecimal::SEVEN);
151 }
152 if self == FPDecimal::ONE / FPDecimal::from(256u128) {
153 return Some(-FPDecimal::EIGHT);
154 }
155 if self == FPDecimal::ONE / FPDecimal::from(512u128) {
156 return Some(-FPDecimal::NINE);
157 }
158 if self == FPDecimal::ONE / FPDecimal::from(1024u128) {
159 return Some(-FPDecimal::TEN);
160 }
161 if self == FPDecimal::ONE / FPDecimal::from(2048u128) {
162 return Some(-FPDecimal::ELEVEN);
163 }
164 if self == FPDecimal::ONE / FPDecimal::from(4096u128) {
165 return Some(-FPDecimal::from(12u128));
166 }
167 if self == FPDecimal::ONE / FPDecimal::from(8192u128) {
168 return Some(-FPDecimal::from(13u128));
169 }
170 if self == FPDecimal::ONE / FPDecimal::from(16384u128) {
171 return Some(-FPDecimal::from(14u128));
172 }
173 if self == FPDecimal::ONE / FPDecimal::from(32768u128) {
174 return Some(-FPDecimal::from(15u128));
175 }
176 None
177 }
178
179 pub(crate) fn log3(self) -> Option<FPDecimal> {
180 if self == FPDecimal::ONE {
181 return Some(FPDecimal::ZERO);
182 }
183 if self == FPDecimal::THREE {
184 return Some(FPDecimal::ONE);
185 }
186 if self == FPDecimal::NINE {
187 return Some(FPDecimal::TWO);
188 }
189 if self == FPDecimal::from(27u128) {
190 return Some(FPDecimal::THREE);
191 }
192 if self == FPDecimal::from(81u128) {
193 return Some(FPDecimal::FOUR);
194 }
195 if self == FPDecimal::from(243u128) {
196 return Some(FPDecimal::FIVE);
197 }
198 if self == FPDecimal::from(729u128) {
199 return Some(FPDecimal::SIX);
200 }
201 if self == FPDecimal::from(2187u128) {
202 return Some(FPDecimal::SEVEN);
203 }
204 if self == FPDecimal::from(6561u128) {
205 return Some(FPDecimal::EIGHT);
206 }
207 if self == FPDecimal::from(19683u128) {
208 return Some(FPDecimal::NINE);
209 }
210 if self == FPDecimal::from(59049u128) {
211 return Some(FPDecimal::TEN);
212 }
213 if self == FPDecimal::from(177147u128) {
214 return Some(FPDecimal::ELEVEN);
215 }
216 if self == FPDecimal::from(531441u128) {
217 return Some(FPDecimal::from(12u128));
218 }
219 if self == FPDecimal::from(531441u128) {
220 return Some(FPDecimal::from(13u128));
221 }
222 if self == FPDecimal::from(4782969u128) {
223 return Some(FPDecimal::from(14u128));
224 }
225 if self == FPDecimal::from(14348907u128) {
226 return Some(FPDecimal::from(15u128));
227 }
228
229 if self == FPDecimal::ONE / FPDecimal::THREE {
230 return Some(-FPDecimal::ONE);
231 }
232 if self == FPDecimal::ONE / FPDecimal::NINE {
233 return Some(-FPDecimal::TWO);
234 }
235 if self == FPDecimal::ONE / FPDecimal::from(27u128) {
236 return Some(-FPDecimal::THREE);
237 }
238 if self == FPDecimal::ONE / FPDecimal::from(81u128) {
239 return Some(-FPDecimal::FOUR);
240 }
241 if self == FPDecimal::ONE / FPDecimal::from(243u128) {
242 return Some(-FPDecimal::FIVE);
243 }
244 if self == FPDecimal::ONE / FPDecimal::from(729u128) {
245 return Some(-FPDecimal::SIX);
246 }
247 if self == FPDecimal::ONE / FPDecimal::from(2187u128) {
248 return Some(-FPDecimal::SEVEN);
249 }
250 if self == FPDecimal::ONE / FPDecimal::from(6561u128) {
251 return Some(-FPDecimal::EIGHT);
252 }
253 if self == FPDecimal::ONE / FPDecimal::from(19683u128) {
254 return Some(-FPDecimal::NINE);
255 }
256 if self == FPDecimal::ONE / FPDecimal::from(59049u128) {
257 return Some(-FPDecimal::TEN);
258 }
259 if self == FPDecimal::ONE / FPDecimal::from(177147u128) {
260 return Some(-FPDecimal::ELEVEN);
261 }
262 if self == FPDecimal::ONE / FPDecimal::from(531441u128) {
263 return Some(-FPDecimal::from(12u128));
264 }
265 if self == FPDecimal::ONE / FPDecimal::from(531441u128) {
266 return Some(-FPDecimal::from(13u128));
267 }
268 if self == FPDecimal::ONE / FPDecimal::from(4782969u128) {
269 return Some(-FPDecimal::from(14u128));
270 }
271 if self == FPDecimal::ONE / FPDecimal::from(14348907u128) {
272 return Some(-FPDecimal::from(15u128));
273 }
274
275 None
276 }
277
278 pub(crate) fn log5(self) -> Option<FPDecimal> {
279 if self == FPDecimal::ONE {
280 return Some(FPDecimal::ZERO);
281 }
282 if self == FPDecimal::FIVE {
283 return Some(FPDecimal::ONE);
284 }
285 if self == FPDecimal::from(25u128) {
286 return Some(FPDecimal::TWO);
287 }
288 if self == FPDecimal::from(125u128) {
289 return Some(FPDecimal::THREE);
290 }
291 if self == FPDecimal::from(625u128) {
292 return Some(FPDecimal::FOUR);
293 }
294 if self == FPDecimal::from(3125u128) {
295 return Some(FPDecimal::FIVE);
296 }
297 if self == FPDecimal::from(15625u128) {
298 return Some(FPDecimal::SIX);
299 }
300 if self == FPDecimal::from(78125u128) {
301 return Some(FPDecimal::SEVEN);
302 }
303 if self == FPDecimal::from(3906251u128) {
304 return Some(FPDecimal::EIGHT);
305 }
306 if self == FPDecimal::from(1953125u128) {
307 return Some(FPDecimal::NINE);
308 }
309 if self == FPDecimal::from(9765625u128) {
310 return Some(FPDecimal::TEN);
311 }
312 if self == FPDecimal::from(48828125u128) {
313 return Some(FPDecimal::ELEVEN);
314 }
315 if self == FPDecimal::from(244140625u128) {
316 return Some(FPDecimal::from(12u128));
317 }
318 if self == FPDecimal::from(1220703125u128) {
319 return Some(FPDecimal::from(13u128));
320 }
321 if self == FPDecimal::from(6103515625u128) {
322 return Some(FPDecimal::from(14u128));
323 }
324 if self == FPDecimal::from(30517578125u128) {
325 return Some(FPDecimal::from(15u128));
326 }
327
328 if self == FPDecimal::ONE / FPDecimal::FIVE {
329 return Some(-FPDecimal::ONE);
330 }
331 if self == FPDecimal::ONE / FPDecimal::from(25u128) {
332 return Some(-FPDecimal::TWO);
333 }
334 if self == FPDecimal::ONE / FPDecimal::from(125u128) {
335 return Some(-FPDecimal::THREE);
336 }
337 if self == FPDecimal::ONE / FPDecimal::from(625u128) {
338 return Some(-FPDecimal::FOUR);
339 }
340 if self == FPDecimal::ONE / FPDecimal::from(3125u128) {
341 return Some(-FPDecimal::FIVE);
342 }
343 if self == FPDecimal::ONE / FPDecimal::from(15625u128) {
344 return Some(-FPDecimal::SIX);
345 }
346 if self == FPDecimal::ONE / FPDecimal::from(78125u128) {
347 return Some(-FPDecimal::SEVEN);
348 }
349 if self == FPDecimal::ONE / FPDecimal::from(3906251u128) {
350 return Some(-FPDecimal::EIGHT);
351 }
352 if self == FPDecimal::ONE / FPDecimal::from(1953125u128) {
353 return Some(-FPDecimal::NINE);
354 }
355 if self == FPDecimal::ONE / FPDecimal::from(9765625u128) {
356 return Some(-FPDecimal::TEN);
357 }
358 if self == FPDecimal::ONE / FPDecimal::from(48828125u128) {
359 return Some(-FPDecimal::ELEVEN);
360 }
361 if self == FPDecimal::ONE / FPDecimal::from(244140625u128) {
362 return Some(-FPDecimal::from(12u128));
363 }
364 if self == FPDecimal::ONE / FPDecimal::from(1220703125u128) {
365 return Some(-FPDecimal::from(13u128));
366 }
367 if self == FPDecimal::ONE / FPDecimal::from(6103515625u128) {
368 return Some(-FPDecimal::from(14u128));
369 }
370 if self == FPDecimal::ONE / FPDecimal::from(30517578125u128) {
371 return Some(-FPDecimal::from(15u128));
372 }
373
374 None
375 }
376
377 pub(crate) fn log7(self) -> Option<FPDecimal> {
379 if self == FPDecimal::ONE {
380 return Some(FPDecimal::ZERO);
381 }
382 if self == FPDecimal::SEVEN {
383 return Some(FPDecimal::ONE);
384 }
385 if self == FPDecimal::from(49u128) {
386 return Some(FPDecimal::TWO);
387 }
388 if self == FPDecimal::from(343u128) {
389 return Some(FPDecimal::THREE);
390 }
391 if self == FPDecimal::from(2401u128) {
392 return Some(FPDecimal::FOUR);
393 }
394 if self == FPDecimal::from(16807u128) {
395 return Some(FPDecimal::FIVE);
396 }
397 if self == FPDecimal::from(117649u128) {
398 return Some(FPDecimal::SIX);
399 }
400 if self == FPDecimal::from(823543u128) {
401 return Some(FPDecimal::SEVEN);
402 }
403 if self == FPDecimal::from(5764801u128) {
404 return Some(FPDecimal::EIGHT);
405 }
406 if self == FPDecimal::from(40353607u128) {
407 return Some(FPDecimal::NINE);
408 }
409 if self == FPDecimal::from(282475249u128) {
410 return Some(FPDecimal::TEN);
411 }
412 if self == FPDecimal::from(1977326743u128) {
413 return Some(FPDecimal::ELEVEN);
414 }
415 if self == FPDecimal::from(13841287201u128) {
416 return Some(FPDecimal::from(12u128));
417 }
418 if self == FPDecimal::from(96889010407u128) {
419 return Some(FPDecimal::from(13u128));
420 }
421 if self == FPDecimal::from(678223072849u128) {
422 return Some(FPDecimal::from(14u128));
423 }
424 if self == FPDecimal::from(4747561509943u128) {
425 return Some(FPDecimal::from(15u128));
426 }
427
428 if self == FPDecimal::ONE / FPDecimal::SEVEN {
429 return Some(-FPDecimal::ONE);
430 }
431 if self == FPDecimal::ONE / FPDecimal::from(49u128) {
432 return Some(-FPDecimal::TWO);
433 }
434 if self == FPDecimal::ONE / FPDecimal::from(343u128) {
435 return Some(-FPDecimal::THREE);
436 }
437 if self == FPDecimal::ONE / FPDecimal::from(2401u128) {
438 return Some(-FPDecimal::FOUR);
439 }
440 if self == FPDecimal::ONE / FPDecimal::from(16807u128) {
441 return Some(-FPDecimal::FIVE);
442 }
443 if self == FPDecimal::ONE / FPDecimal::from(117649u128) {
444 return Some(-FPDecimal::SIX);
445 }
446 if self == FPDecimal::ONE / FPDecimal::from(823543u128) {
447 return Some(-FPDecimal::SEVEN);
448 }
449 if self == FPDecimal::ONE / FPDecimal::from(5764801u128) {
450 return Some(-FPDecimal::EIGHT);
451 }
452 if self == FPDecimal::ONE / FPDecimal::from(40353607u128) {
453 return Some(-FPDecimal::NINE);
454 }
455 if self == FPDecimal::ONE / FPDecimal::from(282475249u128) {
456 return Some(-FPDecimal::TEN);
457 }
458 if self == FPDecimal::ONE / FPDecimal::from(1977326743u128) {
459 return Some(-FPDecimal::ELEVEN);
460 }
461 if self == FPDecimal::ONE / FPDecimal::from(13841287201u128) {
462 return Some(-FPDecimal::from(12u128));
463 }
464 if self == FPDecimal::ONE / FPDecimal::from(96889010407u128) {
465 return Some(-FPDecimal::from(13u128));
466 }
467 if self == FPDecimal::ONE / FPDecimal::from(678223072849u128) {
468 return Some(-FPDecimal::from(14u128));
469 }
470 if self == FPDecimal::ONE / FPDecimal::from(4747561509943u128) {
471 return Some(-FPDecimal::from(15u128));
472 }
473
474 None
475 }
476
477 pub(crate) fn log10(self) -> Option<FPDecimal> {
478 if self == FPDecimal::ONE {
479 return Some(FPDecimal::ZERO);
480 }
481 if self == FPDecimal::TEN {
482 return Some(FPDecimal::ONE);
483 }
484 if self == FPDecimal::from(100u128) {
485 return Some(FPDecimal::TWO);
486 }
487 if self == FPDecimal::from(1_000u128) {
488 return Some(FPDecimal::THREE);
489 }
490 if self == FPDecimal::from(10_000u128) {
491 return Some(FPDecimal::FOUR);
492 }
493 if self == FPDecimal::from(100_000u128) {
494 return Some(FPDecimal::FIVE);
495 }
496 if self == FPDecimal::from(1_000_000u128) {
497 return Some(FPDecimal::SIX);
498 }
499 if self == FPDecimal::from(10_000_000u128) {
500 return Some(FPDecimal::SEVEN);
501 }
502 if self == FPDecimal::from(100_000_000u128) {
503 return Some(FPDecimal::EIGHT);
504 }
505 if self == FPDecimal::from(1_000_000_000u128) {
506 return Some(FPDecimal::NINE);
507 }
508 if self == FPDecimal::from(10_000_000_000u128) {
509 return Some(FPDecimal::TEN);
510 }
511 if self == FPDecimal::from(100_000_000_000u128) {
512 return Some(FPDecimal::ELEVEN);
513 }
514 if self == FPDecimal::from(1_000_000_000_000u128) {
515 return Some(FPDecimal::from(12u128));
516 }
517 if self == FPDecimal::from(10_000_000_000_000u128) {
518 return Some(FPDecimal::from(13u128));
519 }
520 if self == FPDecimal::from(100_000_000_000_000u128) {
521 return Some(FPDecimal::from(14u128));
522 }
523 if self == FPDecimal::from(1_000_000_000_000_000u128) {
524 return Some(FPDecimal::from(15u128));
525 }
526
527 if self == FPDecimal::ONE / FPDecimal::TEN {
528 return Some(-FPDecimal::ONE);
529 }
530 if self == FPDecimal::ONE / FPDecimal::from(100u128) {
531 return Some(-FPDecimal::TWO);
532 }
533 if self == FPDecimal::ONE / FPDecimal::from(1_000u128) {
534 return Some(-FPDecimal::THREE);
535 }
536 if self == FPDecimal::ONE / FPDecimal::from(10_000u128) {
537 return Some(-FPDecimal::FOUR);
538 }
539 if self == FPDecimal::ONE / FPDecimal::from(100_000u128) {
540 return Some(-FPDecimal::FIVE);
541 }
542 if self == FPDecimal::ONE / FPDecimal::from(1_000_000u128) {
543 return Some(-FPDecimal::SIX);
544 }
545 if self == FPDecimal::ONE / FPDecimal::from(10_000_000u128) {
546 return Some(-FPDecimal::SEVEN);
547 }
548 if self == FPDecimal::ONE / FPDecimal::from(100_000_000u128) {
549 return Some(-FPDecimal::EIGHT);
550 }
551 if self == FPDecimal::ONE / FPDecimal::from(1_000_000_000u128) {
552 return Some(-FPDecimal::NINE);
553 }
554 if self == FPDecimal::ONE / FPDecimal::from(10_000_000_000u128) {
555 return Some(-FPDecimal::TEN);
556 }
557 if self == FPDecimal::ONE / FPDecimal::from(100_000_000_000u128) {
558 return Some(-FPDecimal::ELEVEN);
559 }
560 if self == FPDecimal::ONE / FPDecimal::from(1_000_000_000_000u128) {
561 return Some(-FPDecimal::from(12u128));
562 }
563 if self == FPDecimal::ONE / FPDecimal::from(10_000_000_000_000u128) {
564 return Some(-FPDecimal::from(13u128));
565 }
566 if self == FPDecimal::ONE / FPDecimal::from(100_000_000_000_000u128) {
567 return Some(-FPDecimal::from(14u128));
568 }
569 if self == FPDecimal::ONE / FPDecimal::from(1_000_000_000_000_000u128) {
570 return Some(-FPDecimal::from(15u128));
571 }
572
573 None
574 }
575
576 pub(crate) fn log11(self) -> Option<FPDecimal> {
578 if self == FPDecimal::ONE {
579 return Some(FPDecimal::ZERO);
580 }
581 if self == FPDecimal::ELEVEN {
582 return Some(FPDecimal::ONE);
583 }
584 if self == FPDecimal::from(121u128) {
585 return Some(FPDecimal::TWO);
586 }
587 if self == FPDecimal::from(1331u128) {
588 return Some(FPDecimal::THREE);
589 }
590 if self == FPDecimal::from(14641u128) {
591 return Some(FPDecimal::FOUR);
592 }
593 if self == FPDecimal::from(161051u128) {
594 return Some(FPDecimal::FIVE);
595 }
596 if self == FPDecimal::from(1771561u128) {
597 return Some(FPDecimal::SIX);
598 }
599 if self == FPDecimal::from(19487171u128) {
600 return Some(FPDecimal::SEVEN);
601 }
602 if self == FPDecimal::from(214358881u128) {
603 return Some(FPDecimal::EIGHT);
604 }
605 if self == FPDecimal::from(2357947691u128) {
606 return Some(FPDecimal::NINE);
607 }
608 if self == FPDecimal::from(25937424601u128) {
609 return Some(FPDecimal::TEN);
610 }
611 if self == FPDecimal::from(285311670611u128) {
612 return Some(FPDecimal::ELEVEN);
613 }
614 if self == FPDecimal::from(3138428376721u128) {
615 return Some(FPDecimal::from(12u128));
616 }
617 if self == FPDecimal::from(34522712143931u128) {
618 return Some(FPDecimal::from(13u128));
619 }
620 if self == FPDecimal::from(379749833583241u128) {
621 return Some(FPDecimal::from(14u128));
622 }
623 if self == FPDecimal::from(4177248169415651u128) {
624 return Some(FPDecimal::from(15u128));
625 }
626
627 if self == FPDecimal::ONE / FPDecimal::ELEVEN {
628 return Some(-FPDecimal::ONE);
629 }
630 if self == FPDecimal::ONE / FPDecimal::from(121u128) {
631 return Some(-FPDecimal::TWO);
632 }
633 if self == FPDecimal::ONE / FPDecimal::from(1331u128) {
634 return Some(-FPDecimal::THREE);
635 }
636 if self == FPDecimal::ONE / FPDecimal::from(14641u128) {
637 return Some(-FPDecimal::FOUR);
638 }
639 if self == FPDecimal::ONE / FPDecimal::from(161051u128) {
640 return Some(-FPDecimal::FIVE);
641 }
642 if self == FPDecimal::ONE / FPDecimal::from(1771561u128) {
643 return Some(-FPDecimal::SIX);
644 }
645 if self == FPDecimal::ONE / FPDecimal::from(19487171u128) {
646 return Some(-FPDecimal::SEVEN);
647 }
648 if self == FPDecimal::ONE / FPDecimal::from(214358881u128) {
649 return Some(-FPDecimal::EIGHT);
650 }
651 if self == FPDecimal::ONE / FPDecimal::from(2357947691u128) {
652 return Some(-FPDecimal::NINE);
653 }
654 if self == FPDecimal::ONE / FPDecimal::from(25937424601u128) {
655 return Some(-FPDecimal::TEN);
656 }
657 if self == FPDecimal::ONE / FPDecimal::from(285311670611u128) {
658 return Some(-FPDecimal::ELEVEN);
659 }
660 if self == FPDecimal::ONE / FPDecimal::from(3138428376721u128) {
661 return Some(-FPDecimal::from(12u128));
662 }
663 if self == FPDecimal::ONE / FPDecimal::from(34522712143931u128) {
664 return Some(-FPDecimal::from(13u128));
665 }
666 if self == FPDecimal::ONE / FPDecimal::from(379749833583241u128) {
667 return Some(-FPDecimal::from(14u128));
668 }
669 if self == FPDecimal::ONE / FPDecimal::from(4177248169415651u128) {
670 return Some(-FPDecimal::from(15u128));
671 }
672
673 None
674 }
675
676 fn _log(a: FPDecimal, base: FPDecimal) -> FPDecimal {
677 if a == FPDecimal::ONE {
680 return FPDecimal::ZERO;
681 }
682
683 a.ln() / base.ln()
684 }
685
686 pub fn log(&self, base: FPDecimal) -> Result<FPDecimal, FPDecimalError> {
687 assert!(base > FPDecimal::ZERO);
688 if *self == FPDecimal::ONE {
689 return Ok(FPDecimal::ZERO);
690 }
691 if self.is_zero() {
692 return Err(FPDecimalError::Undefined("log0 ".to_owned()));
693 }
694
695 if base == FPDecimal::E {
696 return Ok(self.ln());
697 }
698
699 let base_checks: Vec<&dyn Fn(FPDecimal) -> Option<FPDecimal>> = vec![
700 &FPDecimal::log_e,
701 &FPDecimal::log2,
702 &FPDecimal::log3,
703 &FPDecimal::log5,
704 &FPDecimal::log7,
705 &FPDecimal::log10,
706 &FPDecimal::log11,
707 ];
708 for log_fn in base_checks {
709 if let (Some(numerator), Some(denominator)) = (log_fn(*self), log_fn(base)) {
710 return Ok(numerator / denominator);
711 }
712 }
713 Ok(FPDecimal::_log(*self, base))
714 }
715
716 fn _two_agm(mut a0: FPDecimal, mut b0: FPDecimal, tol: FPDecimal) -> FPDecimal {
717 loop {
718 if (a0 - b0).abs() < tol {
719 break;
720 }
721 let a1 = (a0 + b0) / FPDecimal::TWO;
722 let b1 = (a0 * b0).sqrt().unwrap();
723 a0 = a1;
724 b0 = b1;
725 }
726 a0 + b0
727 }
728
729 #[allow(clippy::many_single_char_names)]
730 fn _ln_robust(&self) -> FPDecimal {
731 let two_pow_m = FPDecimal::from(4294967296u128);
737 let s = *self * two_pow_m;
738 let tol = FPDecimal::must_from_str("0.0000001");
739 let a0 = FPDecimal::ONE;
740 let b0 = FPDecimal::FOUR / s;
741 let two_agm = FPDecimal::_two_agm(a0, b0, tol);
742
743 FPDecimal::PI / two_agm - FPDecimal::from(32u128) * FPDecimal::LN2
744 }
745
746 #[allow(clippy::many_single_char_names)]
747 fn _ln(&self) -> FPDecimal {
748 assert!(self.sign != 0);
749 assert!(*self != FPDecimal::ZERO);
750 let mut v = self.num;
751 let mut r = FPDecimal::ZERO;
752 while v <= FPDecimal::ONE.num / U256([10, 0, 0, 0]) {
753 v *= U256([10, 0, 0, 0]);
754 r -= FPDecimal::LN_10;
755 }
756 while v >= U256([10, 0, 0, 0]) * FPDecimal::ONE.num {
757 v /= U256([10, 0, 0, 0]);
758 r += FPDecimal::LN_10;
759 }
760 while v < FPDecimal::ONE.num {
761 v = FPDecimal::_mul(FPDecimal { num: v, sign: 1 }, FPDecimal::E).num;
762 r -= FPDecimal::ONE;
763 }
764 while v > FPDecimal::E.num {
765 v = FPDecimal::_div(FPDecimal { num: v, sign: 1 }, FPDecimal::E).num;
766 r += FPDecimal::ONE;
767 }
768 if v == FPDecimal::ONE.num {
769 return r;
770 }
771 if v == FPDecimal::E.num {
772 return r + FPDecimal::ONE;
773 }
774
775 let frac_1_5_fpdec = FPDecimal {
776 num: U256([3, 0, 0, 0]) * FPDecimal::ONE.num / U256([2, 0, 0, 0]),
777 sign: 1,
778 };
779 let v = FPDecimal { num: v, sign: 1 } - frac_1_5_fpdec;
780
781 r += FPDecimal::LN_1_5;
782
783 let mut m = FPDecimal::ONE * v
784 / (v + FPDecimal {
785 num: U256([3, 0, 0, 0]) * FPDecimal::ONE.num,
786 sign: 1,
787 });
788
789 r += FPDecimal {
790 num: U256([2, 0, 0, 0]) * FPDecimal::ONE.num,
791 sign: 1,
792 } * m;
793 let m2 = m * m / FPDecimal::ONE;
794 let mut i: u64 = 3;
795
796 loop {
797 m = m * m2 / FPDecimal::ONE;
798
799 let fpdec_i = FPDecimal {
800 num: U256([i, 0, 0, 0]) * FPDecimal::ONE.num,
801 sign: 1,
802 };
803 r += FPDecimal {
804 num: U256([2, 0, 0, 0]) * FPDecimal::ONE.num,
805 sign: 1,
806 } * m
807 / fpdec_i;
808 i += 2;
809 if i >= 3 + 2 * FPDecimal::DIGITS as u64 {
810 break;
811 }
812 }
813 r
814 }
815
816 pub fn ln(&self) -> FPDecimal {
817 if *self == FPDecimal::TWO {
818 return FPDecimal::LN2;
819 }
820 if let Some(value) = self.log_e() {
821 return value;
822 }
823 if self.abs() < FPDecimal::must_from_str("1.1") {
824 return self._ln_robust();
825 }
826 self._ln()
827 }
828}
829
830#[cfg(test)]
831mod tests {
832
833 use crate::FPDecimal;
834 use primitive_types::U256;
835
836 #[test]
837 fn test_ln3() {
838 assert_ne!(FPDecimal::THREE.ln(), FPDecimal::must_from_str("1.09861228866810969"));
839 }
840 #[test]
841 fn test_ln_x_smaller_than_1() {
842 assert_eq!((FPDecimal::ONE / FPDecimal::TWO).ln(), FPDecimal::must_from_str("-0.693147180435828445"));
843 assert_eq!(
844 (FPDecimal::ONE / FPDecimal::THREE).ln(),
845 FPDecimal::must_from_str("-1.098612288365102671")
846 );
847 assert_eq!((FPDecimal::ONE / FPDecimal::NINE).ln(), FPDecimal::must_from_str("-2.197224577273354107"));
848
849 assert_eq!((FPDecimal::ONE / FPDecimal::TEN).ln(), FPDecimal::must_from_str("-2.302585092978637669"));
850 assert_eq!(
851 (FPDecimal::ONE / FPDecimal::ELEVEN).ln(),
852 FPDecimal::must_from_str("-2.397895272724232098")
853 );
854 assert_eq!(
855 (FPDecimal::ONE / FPDecimal::from(20u128)).ln(),
856 FPDecimal::must_from_str("-2.995732273537724492")
857 );
858 assert_eq!(
859 (FPDecimal::ONE / FPDecimal::from(30u128)).ln(),
860 FPDecimal::must_from_str("-3.401197381645697712")
861 );
862 }
863
864 #[test]
865 fn test_ln_x_greater_than_1() {
866 assert_eq!(FPDecimal::must_from_str("1.0001").ln(), FPDecimal::must_from_str("0.000099995720261047"));
867 assert_eq!(FPDecimal::must_from_str("1.001").ln(), FPDecimal::must_from_str("0.000999500798628942"));
868 assert_eq!(FPDecimal::must_from_str("1.1").ln(), FPDecimal::must_from_str("0.095310179804324867"));
869 assert_eq!((FPDecimal::FIVE / FPDecimal::FOUR).ln(), FPDecimal::must_from_str("0.223143551314209761"));
870 assert_eq!((FPDecimal::must_from_str("100")).ln(), FPDecimal::must_from_str("4.605170185988091368"));
871 assert_eq!((FPDecimal::must_from_str("1000")).ln(), FPDecimal::must_from_str("6.907755278982137052"));
872 assert_eq!((FPDecimal::must_from_str("10000")).ln(), FPDecimal::must_from_str("9.210340371976182736"));
873 assert_eq!(
874 (FPDecimal::must_from_str("100000")).ln(),
875 FPDecimal::must_from_str("11.51292546497022842")
876 );
877 assert_eq!(
878 (FPDecimal::must_from_str("1000000")).ln(),
879 FPDecimal::must_from_str("13.815510557964274104")
880 );
881 assert_eq!(
882 (FPDecimal::must_from_str("10000000")).ln(),
883 FPDecimal::must_from_str("16.118095650958319788")
884 );
885 }
886
887 #[test]
888 fn test_ln() {
889 assert_eq!(FPDecimal::E.ln(), FPDecimal::ONE);
890 }
891
892 #[test]
893 fn test_ln10() {
894 assert_eq!(
895 FPDecimal {
896 num: U256([10, 0, 0, 0]) * FPDecimal::ONE.num,
897 sign: 1
898 }
899 .ln(),
900 FPDecimal::LN_10
901 );
902 }
903 #[test]
904 fn test_log_2_8() {
905 assert_eq!(FPDecimal::EIGHT.log(FPDecimal::TWO).unwrap(), FPDecimal::THREE);
906 }
907
908 #[test]
909 fn test_log_11_8() {
910 assert_eq!(
911 FPDecimal::EIGHT.log(FPDecimal::ELEVEN).unwrap(),
912 FPDecimal::must_from_str("0.867194478953663578")
913 );
914 }
915
916 #[test]
917 fn test_ln1_5() {
918 let three = FPDecimal {
919 num: U256([3, 0, 0, 0]) * FPDecimal::ONE.num,
920 sign: 1,
921 };
922 let two = FPDecimal {
923 num: U256([2, 0, 0, 0]) * FPDecimal::ONE.num,
924 sign: 1,
925 };
926 let one_point_five = FPDecimal::_div(three, two);
927 assert_eq!(one_point_five.ln(), FPDecimal::LN_1_5);
928 }
929
930 #[test]
931 fn test_ln2_3() {
932 let three = FPDecimal {
933 num: U256([3, 0, 0, 0]) * FPDecimal::ONE.num,
934 sign: 1,
935 };
936 let two = FPDecimal {
937 num: U256([2, 0, 0, 0]) * FPDecimal::ONE.num,
938 sign: 1,
939 };
940 let two_point_three = two + three / FPDecimal::from(10u128);
941 assert_eq!(two_point_three.ln(), FPDecimal::must_from_str("0.832909122935103999"));
942 }
943
944 #[test]
945 fn test_ln4_16() {
946 let a = FPDecimal::from(16u128);
947 let b = FPDecimal::FOUR;
948 assert_eq!(a.log(b).unwrap(), FPDecimal::TWO);
949 }
950
951 #[test]
952 fn test_log_e_16() {
953 let a = FPDecimal::from(16u128);
954 let b = FPDecimal::FOUR;
955 assert_eq!(a.log(b).unwrap(), FPDecimal::TWO);
956 }
957}