dashu-float 0.6.2

Arbitrary-precision float math library for Rust with arbitrary base and arbitrary rounding mode. Provides FBig, DBig, and CachedFBig with efficient base conversion, the hexadecimal float format used by C++ programs, and parsing and formatting in base 2-36. Transcendentals (exp, ln, trig, hyperbolic, powers, roots, pi) are correctly rounded; optional serde, rand, num-traits, rkyv, and zeroize.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
# Changelog

## 0.6.2

### Change
- **Behavior change** (released as a patch: no API surface changes — the fixed
  nearest-ties-away rule was the reported defect): the remainder operator (`%` / `RemAssign` /
  `Context::rem`) now rounds the quotient with the rounding mode attached to the type
  (issues #110, #111). `DBig`/`FBig<HalfAway>` results are
  unchanged; `FBig<Zero>` (the binary default) now returns the truncated,
  dividend-signed remainder — fmod semantics, so `fbig!(0xF) % fbig!(0xA)` is `+5`;
  `FBig<HalfEven>` now implements the IEEE 754 `remainder` rule (ties to even); `Down`/
  `Up` round the quotient floor/ceil-style (Python-style `%` and its mirror). The mode
  also continues to round the remainder value to the context precision as before, and
  `RemEuclid` is unchanged. The kernel reduces modulo `2·|rhs|` on its fast path, so the
  `HalfEven` tie parity falls out of the same residue with no extra pass.
- Clarified the docstrings around rounding-to-integer (issue #110): `FBig::round` now
  states that it always rounds half away from zero like `f64::round()`, regardless of the
  rounding mode attached to the type, and points to the mode-aware alternatives
  (`to_int()`, `quantize(0)`, `with_precision()`); `to_int()` and `quantize()` cross-link
  back.
- Specialized the ×2 pattern out of `Mag`'s power-of-two scaling: the propagation folds'
  `mul_pow2(1)` cross-terms now call a dedicated `const #[inline] mul2()` (a normalized
  significand never renormalizes on a single doubling, so it is a bare exponent bump,
  inlinable cross-crate), and every other caller migrated to the general scaling at the
  internal `i128` exponent width — now the one `mul_pow2` (the `isize`-width wrapper and
  the `_i128` suffix are gone). The single-user kernels `add_up`/`sub_impl` are inlined
  into `add`/`sub_down`, and `exp_upper` keeps its halving exponent in `i128` end to end
  (no `usize` round-trip). The raw-parts assembler became an idiomatic private
  `Mag::new(man, exp)` associated constructor (absorbing `from_pow2_stored`'s duplicate
  saturation check), and the too-large-significand round-up normalizer likewise became
  `Mag::new_round_up(raw, exp)`; `new` debug-asserts the normalization contract, so the
  test suite validates it at every construction path. No observable behavior change.
- Pruned the internal `Mag` radius type down to the subset the float/complex error
  propagation actually uses: removed the round-up `Mag::sub` (dead since the complex log
  bracket switched to `sub_down`; its helper `from_double_rounded` collapsed to a
  truncating `from_double_truncated`), replaced the generic binary-exponentiation
  `Mag::pow` with a plain squaring helper (`exp_upper` only ever raises to `2^j`), dropped
  the unused `Hash` derive, and made `from_pow2` module-private.
  Bit-identical results on every live path (`Mag` stays `#[doc(hidden)]`, so no public API
  changes).

### Fix
- `tanh` no longer stalls on large `|x|`: the value saturates at `sign(x)·(1 − 2e^{−2|x|})`,
  whose sub-half-ulp residual makes the Ziv working-precision mid collapse onto exactly `±1`
  — the boundary of a one-sided directed-rounding preimage — so the containment test could
  never certify and the loop climbed toward a working precision of `~2|x|/ln 2` (an effective
  hang at `|x| = 10⁵`, minutes at `|x| ≈ 1.7·10⁶`; the positive side's overflow shortcut was
  unreachable for the same reason). Inputs beyond `|x| > (p·ln B + ln 4)/2` (where the residual
  is provably below half an ulp) now short-circuit to the mode-aware `±1` endpoint before the
  loop — the same gate `exp_m1` already had for its extreme-negative case (`exp_extreme_negative`,
  generalized to both signs as the shared `near_one_endpoint`). Directed modes return the
  ulp-inside neighbor (`Up`/`Zero` just above `−1`, `Down`/`Zero` just below `+1`) instead of
  the mode-blind `+1`.

## 0.6.1

### Add
- `#[doc(hidden)]` lockstep-shared re-exports of the internal error-propagation substrate
  (`Ball`, `Mag`, `ulp_mag`) at the crate root, consumed by `dashu-cmplx`'s complex ball
  (`CBall`) for its transcendental radius migration. Deliberately hidden: excluded from the
  semver and stability guarantees, consumed only by this repository's crates (released
  together). No documented API changes.
- ×u trigonometric functions `sin_unit`/`cos_unit`/`sin_cos_unit`/`tan_unit` (of `2π·x/u`, the
  argument in units of the full turn divided by `u` — e.g. `u = 360` gives degrees) and their
  inverses `asin_unit`/`acos_unit`/`atan_unit`/`atan2_unit` (of `u·θ/(2π)`), on `Context`,
  `FBig` and `CachedFBig` (the `u` parameter is `usize`; the forward family takes
  `Err(OutOfDomain)` at `u = 0`, the inverse family returns the `u → 0` signed-zero limit).
  Unlike the radian variants, the argument reduces *exactly* mod u in integer arithmetic, so
  the accuracy is independent of the magnitude of the input; arguments where `12x/u` (resp.
  `8x/u` for the tangent) is an integer resolve exactly — quarters (`0`/`±1`), the sine/cosine
  sixths (`±1/2`), the tangent eighths (`±1`) and the tangent poles (`Err(Indeterminate)`,
  where the one-sided limits `+∞`/`−∞` disagree in sign). The inverse family resolves the
  axis/diagonal angles to exact `k·u/8` values (including the finite `y = ±x` diagonals, which
  an exactly-representable one-sided directed-rounding preimage would leave uncertifiable).
- ×π trigonometric functions `sin_pi`/`cos_pi`/`sin_cos_pi`/`tan_pi` (of `x·π`), on `Context`,
  `FBig` and `CachedFBig` — now thin wrappers over the ×u family at `u = 2`.
- ×π hyperbolic functions `sinh_pi`/`cosh_pi`/`sinh_cosh_pi` (of `x·π`), on `Context`, `FBig` and
  `CachedFBig` — the argument ball is built from the shared cached π; a direct series handles
  `|πx| ≤ 1`, the exponential composition the rest.

### Change
- **(internal, `tuning`) the per-attempt Ziv radius trace is now a settable hook** instead of an
  unconditional `eprintln!`: `ziv_set_trace_hook(Some(|guard, radius| …))` (deliberately
  `#[doc(hidden)]` — a profiling hook, not a stable API promise) installs a printer, and the
  default `None` costs one `Cell` read per attempt. The unconditional print cost ~3–4 µs per
  attempt, which silently poisoned any *timing* run built with `tuning` (reading as a 4–5×
  regression on sub-microsecond Ziv cases).
- **`-0` renders with its sign**, as `f64`'s does: `format!("{}", -0)` is now `"-0"` (was `"0"`)
  and `format!("{:e}", -0)` is `"-0e0"` (was `"0e0"`). The parse side moves with it — `"-0"`,
  `"-0.0"` and `"-0e0"` now produce *negative* zero (all three produced `+0`) — so a signed zero
  survives its own `Display`/`FromStr` round-trip. Neither direction could express the sign
  before, which is why the pair is fixed together. Nothing numeric changes (`±0` compare equal)
  and `{:+}` still prints `"+0"` for the positive zero.
- **(internal) the Ziv error radius is now a value-space `Mag` instead of an exact-integer
  ulp count** (`float/src/mag.rs`, `float/src/ball.rs`; both `pub(crate)`). Every `+`/`-`/`*`/`/`
  in a transcendental's algorithm is itself correctly rounded, so the radius composes through
  plain interval algebra over the operation's operands — no ulp-domain shift formulas, no
  per-ball precision state, and no `IBig` error bookkeeping. Results are unchanged for every
  input (validated bit-exact against MPFR/MPC); this is the mechanism the 0.6.0 note below
  described as "an exact-integer error count", replaced.
- **(internal) the operand error of the *input* to a transcendental is now part of the
  certified radius** rather than a per-function hand estimate, so a result that sits close to
  a rounding boundary is retried instead of being rounded the wrong way. See the two `Fix`
  entries below, which are the user-visible symptoms of the old per-function estimates.
- **(internal) faster digit bookkeeping in division**: `digit_len` on a power-of-two base is
  now a plain bit length (`ilog` allocated a `B^log` buffer only to discard it). No perf
  regression from the fixes below: `FBig / FBig` at parity or faster at all benched
  precisions, `DBig / DBig` ~10% faster at 10³–10⁴ digits (+8% at 10 digits, the cost of the
  now-correct wide-quotient rounding), `nth_root` 10–45% faster.
- **(internal) the ×u reduction's modular exponentiation delegates to `dashu-int`**
  (`ConstDivisor::reduce` + `Reduced::pow`) instead of a local binary-exponentiation loop
  over `rem_euclid` — the small `2k·u` modulus rides the single/double-word fast paths. The
  log₂ helpers (`log2_base`'s fixed-point bracket, the conservative `log2_u_bs_lb` bound)
  moved to `utils.rs`, next to the digit helpers that share their role.

### Fix
- **the internal radius type `Mag` widens its exponent field to `i128`** (was `isize`): a
  result in `10^(2.8e18)..10^(9.2e18)` — e.g. `sinh_pi(3.5e18)`, finite and representable as
  an `FBig` — used to saturate its *radius* bookkeeping to `+∞` (`Mag`'s ceiling was
  `2^isize::MAX ≈ 10^2.8e18`, below the value range), which no Ziv attempt can certify; the
  retry loop then ran its exponential guard growth for hours before erroring. The exponent
  field now covers every representable value, so such results certify in one retry.
  `fuzz/tests/float_trig_random.rs`'s `fbig_sinh_cosh_pi_fuzz` shards (×π hyperbolic at high
  precision) were the visible symptom: they hung for hours at the 500/1000-bit sweep widths.
- **`asin` of an argument that merely *rounds* onto `±1` returned the endpoint** — `asin(1 − 10⁻¹⁵⁵)`
  at 100 digits gave exactly `π/2` where the true value is `π/2 − 1.4·10⁻⁷⁸` (~10⁹ ulps off), and
  the Ziv loop certified it because the endpoint branch reports only a few ulps of radius. The
  argument is not the endpoint: `√(1−x²)` merely *collapsed* onto zero at the work precision, and
  `Ball::sqrt` returned that zero with the radius dropped. A rounded-to-zero root now carries the
  whole-line radius instead (only an *exact* zero stays exact), so the `±1` branch is taken for an
  exact `±1` argument alone and everything else retries at a higher guard, where the argument is
  representable and the general `atan(x/√(1−x²))` path computes the true `√(2δ)` offset. The same
  applies to the ×u inverses (`asin_unit`/`acos_unit`). The domain checks and `±1` rows now compare
  the raw `Repr` explicitly rather than relying on `FBig::ONE` being unlimited-precision for the
  same effect (behaviourally identical; `repr_cmp_same_base`'s precision argument and the poles'
  exactness requirement are documented on it).
- **`ln_1p` of an argument that rounds onto the pole at `−1` panicked** (debug: `attempt to
  subtract with overflow`; release: a wrapped nonsense exponent) — the `1 + x` cancellation left
  `ln_compute` with a zero midpoint, where `log2_bounds` saturates to `−∞`. A zero midpoint (and a
  `ln_1p` ball reaching the pole, as `atanh`'s `2x/(1−x)` does at the first attempt) now reports the
  whole-line radius, so the Ziv loop retries at a guard where the argument is representable.
- **A whole-line (`Mag::INFINITY`) radius panicked the Ziv containment test** instead of forcing a
  retry: the exported radius is a `Repr` infinity, and the test's `a ± e` arithmetic asserts its
  operands finite. It now short-circuits to "not contained", which is what the degenerate-denominator
  (`Ball::div`), pole and rounded-root paths documented as their retry signal.
- **32-bit `Word` targets returned a wrong `log₂ BASE` from the fixed-point walk** (the
  compile-time bracket behind the generic-base radius rules): the normalization shifted with
  `Word::leading_zeros`, so on `Word = u32` (e.g. the `i686` CI target) `log2(10)` came out
  ≈ 35 instead of ≈ 3.32 — radii then inflated by orders of magnitude, saturated to infinity
  inside the `atan` reduction and panicked the Ziv containment test (`atan2` of any
  non-unit-scaled pair). The walk is now pinned to explicit widths; a value-pinning test
  guards it.
- **The MSRV (1.68) workspace check failed on a std-only `f32::abs`** in `exp`'s
  overflow probe (that check compiles `dashu-float` without `std`; the inherent method is
  core-only from 1.85) — it now goes through the `Abs` trait, which is no_std-safe.
- **`no_std` test builds failed to compile**: the Ziv retry-count regression tests read the
  `thread_local` counter that only exists under `std`; those tests are now
  `#[cfg(feature = "std")]`, matching the `ziv.rs` test module's own gate.
- **Performance regressions of the Mag/Ball migration**: the
  two-stage `ln` reduction fired its cancellation double-precision on inputs that reduce to
  *exactly* a power of two (`ln(1e100)` in base 10 was 9× slower than the pre-migration
  code at 600 digits) — the cancellation condition now reads off the rounded input directly
  (one exact comparison) instead of the split exponents, and the power-two floor is settled
  by an exact comparison at the boundary. The generic-base radius rules (`scale_by_base_pow`
  and `to_repr`'s base-power export) no longer build `BASE^|e|` bigints per call — a
  compile-time fixed-point `log₂ BASE` bracket replaces them (one-bit tight, sound on either
  side), which was worth 1.5–3× on base-3 `exp` at high precision. `asinh` squares through
  the dedicated `sqr` kernel again, and the base-10 radius export keeps its significand
  instead of collapsing to a bare power of ten (≤ ~1× slack instead of ≤ 10×).
- **`exp`-family results near a rounding boundary paid one systematic Ziv retry** (~2.25×)
  on non-power-of-two bases: the `Bⁿ` powering chain compounds the per-op radius slack past
  the first attempt's preimage. The chain length is now charged to the initial guard
  (`pow_chain_guard`: `n` for `B ≠ 2` on `exp`/`exp_m1` and the hyperbolic family, `2n`
  unconditionally on `powf` — the base-2 `powf` margins are thin enough to need it). All 20
  measured regressions across the sweep are eliminated (18 of the 20 now at or below
  master's own timings; results bit-identical — correct rounding is unique), at the cost of
  a few guard digits on the affected functions.
- **`ln` of a large base power paid one Ziv retry near a rounding boundary**: the
  reconstruction constants (`s2·ln2`, `e_base·lnB`) evaluated at the bare work precision, so
  their 8-ulp radii were amplified by the scale factor (`ln(1e100)` @6 digits carried ~1/3
  of the target half-ulp before the candidate margin). The constants now evaluate with
  `⌈log_B|scale|⌉ + 1` extra digits — the same construction `exp` already uses for its
  `ln(B)` — keeping the amplified radius sub-ulp at a cost confined to inputs with large
  scale factors.
- **`sqrt` under directed modes** (#99): a sticky remainder was rounded *down* under
  `Up`/`Away` when the integer root carries `precision + 1` digits (`Up(sqrt(6))² < 6` at
  p53) — the final rounding now consults the rounding mode instead of hardcoding half-up.
- **`div` no longer pre-rounds an over-wide dividend** (#100): the kernel bounds it by an
  exact digit split instead, keeping the dropped digits as sticky rounding information.
  The old pre-round could report a false `Exact` (`5/1` @ p1), invert the direction
  (`7/-1` under `Up` gave `-8` instead of `-4`), or land on a false midpoint (`31/4`
  base 3 `HalfEven` gave `6` instead of `9`).
- **`div` now rounds exact and `precision+1`-digit quotients in a single step** (#100):
  an exactly-dividing quotient was returned unreduced (`15/3` @ p2 gave the 3-digit `5`
  instead of `4`), and an over-wide quotient was rounded on the integer instead of the
  precision grid (`3/5` @ p2 gave the unrepresentable `0.625` instead of `0.5`).
- **`div` with a negative divisor and an over-wide dividend** carried the sticky low part
  with the wrong sign (the divisor-sign normalization negates both operands), and the
  `precision+1`-digit quotient's half comparison sign-flipped `B − 2·ql` where only `|ql|`
  enters — the latter mis-rounded negative dividends in non-binary bases under nearest
  modes (`-21/2` base 10 @ p1 `HalfEven` gave `-20` instead of `-10`).
- **`nth_root` no longer double-rounds a `precision+1`-digit root** (#100): the exponent
  alignment now takes the truncating shift when the padding one would grow the root past
  the precision, so one rounding decides (`nth_root(2, 1.75)` @ p2 `HalfEven` gave `1.0`
  instead of `1.5`).
- **`with_base` rounds its exact-conversion shortcuts** (#100): the power-of-base shortcuts
  and small-exponent path returned significands wider than the target precision, and the
  division path pre-rounded its dividend, so the `Exact` flag could be false (`2.1` →
  base 2 reported `Exact`).
- `exp` — and every transcendental built on it, e.g. `sinh`/`cosh` — of an argument whose
  exponent is in the 10^14 range no longer dies on an out-of-memory allocation. The base-aware
  radius export converted a binary exponent to a decimal one (and back) through a small
  rational bound (`28/93` and `30102/100000` for log₁₀2, `3322/1000` and `33218/10000` for
  log₂10). Those err by ~5·10⁻⁵ *relative*, and that error multiplies the exponent: at 10^14 it
  overshot the outward power of ten by `10^1.2e10`, leaving the Ziv error radius astronomically
  larger than the value it bounded — the containment test then tried to align that gap and ran
  out of memory. The conversions now use 64- and 62-bit fixed-point bounds, so the outward
  slack stays under one digit for every `isize` exponent.
- Additions/subtractions of operands with an astronomically large exponent gap (~10⁹+ digits,
  e.g. the two exponentials composing `sinh(1e14)`) no longer die on an out-of-memory
  allocation: the sticky low part of the aligned sum is collapsed to a bounded position when
  it sits entirely below the rounding window (`repr_round_sum`), and the hyperbolic
  `sinh`/`cosh`/`sinh_cosh` compositions drop an exponential that sits below the other's ulp
  window instead of aligning the gap.
- `sqrt` of a perfect square in a non-power-of-two base never returned under the directed
  rounding modes (`Down`/`Up`/`Zero`): it kept doubling its working precision until the retry
  budget was exhausted — `sqrt(4)` in base 10 escalated past 10^8 digits instead of returning
  `2`. `sqrt` was the one transcendental still deriving its Ziv radius by hand (a blanket
  `value.ulp()`), and no nonzero radius fits a one-sided directed preimage (`Down`'s
  `[y, y+ulp)` cannot contain `[y−r, y+r]`), so an exactly-representable root could not be
  certified at all. It now wraps its kernel result as a `Ball`, so an exact root carries
  radius 0 and certifies immediately; an inexact root keeps the same one-ulp bound, and the
  base-2 fast path is untouched.
- `log2`/`ln` of a value a hair above 1 at low precision could return exactly `0`: the Ziv
  containment test accepted a zero candidate whose radius was nonzero, but no nonzero real
  rounds to exactly zero (the documented ±ulp preimage of ±0 is a special case). A zero
  candidate is now certified only with a zero radius. Scoped to this crate's driver — the
  public `ErrorBounds` semantics are unchanged.
- `x + (-0)`, `x - (-0)` and their mirrors returned `0` instead of `x` whenever the exponent
  gap to `-0`'s sentinel exponent (`-1`) reached past the end of `x`'s significand — e.g.
  `1e-16 + (-0)` was `0` at precision 12. The `addsub_*` kernels short-circuited only on
  `+0`, so `-0` fell through to the alignment path, where its sentinel exponent makes it look
  like the *larger* operand and `x`'s significand is shifted out entirely.
- A sum or difference of two *zero* operands now follows IEEE 754 §6.3: `(-0) + (-0)` and
  `(-0) - (+0)` are `-0` (`x + x` retains `x`'s sign, even when `x` is zero); a zero of mixed
  signs is `+0`, or `-0` under roundTowardNegative, as the exact zero of a cancellation
  already was.
- `powf` (and the `powi` fallback for exponents past the squaring chain) no longer stalls
  when the exponentiation drives the `exp` argument far negative — e.g.
  `powf(7.03e71, -84.91)`, whose `y·ln x ≈ −14035` makes the result ≈ `1e-6096`. The
  internal `exp` input-error fold omitted the result's magnitude for a negative argument,
  over-estimating the error radius by `e^{−x}` (hundreds of digits); the Ziv loop could only
  certify by growing its working precision past `|x|/log_B e`, burning 9 retries and ~6000
  digits: 1.5 s at 16 digits instead of 60 µs (and 6.5 s at 151). The fold now scales by the
  result's magnitude, so such calls certify on the first attempt.
- `ln` (and `log2`/`log10`/`ln_1p`, which share its core) of an argument with a huge
  exponent (e.g. `ln(1e1000000000)`) previously never returned, holding gigabytes: the
  argument reduction materialized a power of two spanning the whole exponent *gap*. The
  reduction now splits the magnitude by an exact base-exponent re-tag plus a bounded
  power-of-two finish, so no power of the gap is ever materialized, and the reduction
  arithmetic is exact integer work end to end (the previous single f32 `log2` estimate
  loses hundreds of bits of accuracy once `|log2 x|` approaches 10^9). (issue #103)
- The hyperbolic functions (`sinh`, `cosh`, `sinh_cosh`, `tanh`, `asinh`, `acosh`) now
  fold the *input's own rounding* into the certified error radius. Previously the input
  was rounded to the working precision and the rounding error dropped, which understated
  the radius by the ulp of the *original* magnitude — fatal for `acosh` near 1, where the
  `x−1` cancellation shrinks the value (and its ulp) while the inherited error does not:
  `acosh` could certify the wrong neighbour of a decimal tie (issue #102). All six now
  thread the input ball (or pass the raw repr into `exp_compute`/`ln_compute`, which fold
  it themselves).
- `ConstCache::pi` (and `Context::pi`) now compute one extra Chudnovsky series term,
  fixing an off-by-1-ulp mis-rounding at certain precisions (previously the term count
  provided only the ceiling — no accuracy headroom — so the series truncation error
  could push the result to the wrong side of a rounding boundary).
- `FBig::with_precision` (and `CachedFBig::with_precision`) now rounds an *unlimited*-
  precision source down to a finite target precision. Previously the shrink guard
  compared context precisions (`0 > N` is always false), so an unlimited value kept its
  full significand and the result violated the precision invariant.
- **(internal) `Ball`'s square rule folded only one `|mid|·rad` cross term** where
  `(m ± r)² = m² ± 2mr + r²` needs two — an under-bound by exactly `‖m‖·r` (the doc
  comment already stated the `2·`; the code did not). Only `asinh` squares a
  nonzero-radius ball through the dedicated `sqr` kernel, so the blast radius was its
  input-error term; the corner-coverage regression pins both `(m ± r)²` extremes.
- `hypot` of two operands past the extreme-exponent scale-down threshold returned
  `Err(Overflow)` whenever the result was not exactly representable (e.g.
  `hypot(7·2^e, 4·2^e) = √65·2^e` at `e ≈ isize::MAX/2`). The rescale factor `k` was
  derived from the *larger* operand's raw exponent only, but base-B normalization can
  leave the smaller value with the larger raw exponent (`4·2^e` normalizes to `1·2^(e+2)`)
  — the smaller operand's square then collided with the infinity sentinel. `k` now scales
  by the larger of the two raw exponents.
- `tan_pi` (and `tan_unit` at any `u`) returned `-0` at the *positive* odd multiples of
  `u/2` unconditionally, breaking oddness (`tan_pi(-1) == tan_pi(1) == -0`) and diverging
  from MPFR (`+0`). Every integer zero of the tangent now carries the sign of the input,
  like the even-multiple row already did.
- `asin_unit(x, 0)`/`acos_unit(x, 0)` returned the `u → 0` limit `±0` for out-of-domain
  `|x| > 1` instead of `Err(OutOfDomain)`. The domain error now outranks the limit (the
  limit of a function undefined at that `x` for every `u > 0` is not `+0`).
- `Sum` of `FBig` lost the sign of an all-`-0` sum: `[-x.zero].sum()` and
  `[-0, -0].sum()` returned `+0` under the nearest modes, while the chained `(-0) + (-0)`
  returns `-0`. The exact accumulator's zero sign now follows the same IEEE 754 §6.3
  left-fold rule as the chained operators (`-0` under roundTowardNegative or when every
  addend is `-0`).
- **(internal) the ×u reduction's f32 magnitude guards are now one-sided-conservative**:
  the bound products `u_lb + s·b_lb` round in f32, and an *upward* rounding of the
  `k = 0` fast-path test could in principle classify a `k ≥ 1` argument as first-quadrant
  (a wrong result; reachable only from gigabit-scale inputs, but a wrongness, not a
  slowdown). The shared bound is shaved by its own f32 slack (`log2_u_bs_lb`), so any
  error falls towards the always-exact general path. The sticky-collapse guard in
  `repr_round_sum` likewise used the upper bound of `log₂B` where the derivation needs
  the lower one, and now carries an explicit margin for the f32 products.
- **(internal) `CachedFBig` mirrors the full ×u family** (`sin_unit`/`cos_unit`/
  `tan_unit`/`asin_unit`/`acos_unit`/`atan_unit`), restoring the drop-in rule that code
  compiling against `FBig` compiles unchanged against `CachedFBig` (only the fused
  `sin_cos_unit`/`atan2_unit` had been mirrored; the forwarding macro cannot pass the
  `u` argument, so these are hand-written wrappers).

## 0.6.0

### Change
- **(breaking) Ziv-backed transcendentals now require `R: ErrorBounds` (not `R: Round`)**: `exp`/
  `exp_m1`/`ln`/`ln_1p`/`log2`/`log10`, `powf`/`powi`, `hypot`, the trig and hyperbolic families
  (incl. inverses), and `FBig::sqrt`. All six built-in modes satisfy `ErrorBounds`; only custom
  non-`ErrorBounds` modes are affected.
- **(breaking) new `FpError::ZivRetryLimitExceeded`** — a Ziv loop that exhausts its retry budget
  (only possible if a radius-bound estimate is wrong) now returns `Err` instead of silently returning
  a possibly-1-ULP-wrong best-effort value.
- **(internal) every transcendental's error radius is now derived mechanically by Ball arithmetic**
  (`float/src/ball.rs`, an exact-integer error count composed through the series/reduction/composition,
  precision-aware) instead of the hand-derived `·ulp` formulas and outward intervals. Behavior
  unchanged, validated bit-exact against MPFR.
- **(internal) `Context::exp` of an astronomically large negative value now returns `Err(Underflow)`**
  (consistent with overflow; the convenience layer is unchanged).
- Removed the `rustversion` dependency (MSRV is 1.68); the unversioned `rand` / `rkyv` feature aliases
  now select the newest versions (`rand_v010` / `rkyv_v08`).

### Add
- **Correctly rounded transcendentals via a Ziv retry loop** — `exp`/`exp_m1`/`ln`/`ln_1p`, `log2`,
  `log10`, `powf`/`powi`, `hypot`, and the trig/hyperbolic families (incl. inverses) certify their
  rounding against the `ErrorBounds` preimage, retrying with more guard digits; exact results report
  radius 0 (MPFR-style `exact` tracking) so directed modes terminate.
- **Base-10 `log10`** (mirrors `log2`, with an exact power-of-ten shortcut).
- **Exact `Add`/`Sub`/`Mul` operators for `Repr`** (new `repr_ops` module) — lossless exact
  intermediates for the Ziv containment test, the correctly-rounded `Sum`, and the `FBig` multiply
  path.
- **`FBig::sqrt` is now correctly rounded** — a `p+1`-digit integer root was previously double-rounded
  (off by 1 ulp at digit boundaries); it now rounds in a single step from the round digit + `sqrtrem`
  remainder (MPFR-style). Power-of-two bases use a fast path; other bases certify via Ziv.
- **`CachedFBig` mirrors the rest of `FBig`'s value surface** (`round`/`trunc`/…/`quantize`,
  `hypot`/`nth_root`, `signum`/`ulp_lb`, base conversions), completing the drop-in mandate.
- `tuning` feature + `ziv_retries()`/`ziv_retries_reset()` for profiling retry counts;
  `Repr::zero_with_sign` public; rkyv 0.7 support (`rkyv_v07`).

### Fix
- **Mode-aware overflow/underflow saturation** — `Err(Overflow)`/`Err(Underflow)` and the
  `FBig → f32`/`f64` conversions now saturate to the directed endpoint per rounding mode (`±∞` /
  largest finite / smallest / `±0`) instead of mode-blind `±∞`/`0`; the `TryFrom` error variant is
  mode-independent.
- **`exp` range reduction for large `|x|`** — `ln B` now carries `⌈log_B|x|⌉+2` extra digits so the
  reduction quotient `s` is pinned (was off by ~`|x|`); the 32-bit `isize` threshold is fixed.
- **Directed `ln`/`log2` near `x ∈ [1, B)`** — the radius now also covers the pre-cancellation `sum`
  scale and the over-delivered `ln_base` context.
- **`FBig → f32`/`f64` subnormal/underflow** — round-to-odd at `width + 24` bits; a
  source-`log2_bounds` short-circuit for catastrophically tiny values.
- `ulp()`/`Repr::cmp` near the exponent ceiling (saturating arithmetic); the `no_std` build (the
  test-only Ziv counter is gated on `std`); `tan` pole check removed (~2× faster).

## 0.5.2

### Add
- `FBig::e` / `Context::e` / `CachedFBig::e`: Euler's number *e*, computed by
  exact-integer binary splitting on `e = Σ 1/k!` (leaf `(1, k, 1)`, reusing the
  universal `(P, Q, T)` merge). Unlike π, *e* is self-contained — it depends on no
  other cached constant and is itself reused by no operation — so it is **not**
  stored in `ConstCache` and `Context::e` takes no cache parameter. The factorial
  series is the optimal algorithm for *e* (asymptotically `O(M(n) log n)` under
  FFT multiplication, i.e. faster than π), and it avoids both the `ln`-based
  argument reduction and the `√p`-fold powering that `exp(1)` would pay for.
- `FBig::fma` / `Context::fma` / `CachedFBig::fma`: fused multiply–add
  `c + sign·(a·b)` with a single rounding. `sign` (`Sign::Positive`/`Sign::Negative`)
  selects add vs subtract, mirroring integer's `add_signed_mul`. It assembles the
  existing exact-product (`make_mul_repr`) and add/round kernels, inheriting their
  severe-cancellation and sticky-tail handling (and the guard digit an effective
  subtraction may leave). The trig quadrant reduction `x − k·(π/2)` now uses it,
  removing one rounding from range reduction. (`sqr` keeps its dedicated, faster
  kernel — don't write `x²` as `fma(x, x, …)`.)

- `FBig::ulp_lb`: a cheap lower bound on `ulp`, guaranteed strictly smaller than it
  (computed from the approximated `digits_lb` rather than the exact digit count). Public
  successor to the internal `sub_ulp`; useful as a conservative negligibility threshold
  (e.g. iterative-method termination). For a rigorous error/radius bound, use `ulp`.
- `Context::addsub_vv` / `addsub_vr` / `addsub_rv` / `addsub_rr`: low-level
  ownership-aware add/subtract kernels computing `lhs + rhs_sign· rhs` directly on
  `Repr` (no `FBig` wrapping, no `Result`) — `Sign::Positive` adds, `Negative`
  subtracts. The four variants cover every ownership combination of the two operands
  (`v` = by-value, `r` = by-ref); each reuses the owned operand's significand buffer
  where it can, avoiding a clone versus the `Context::add`/`sub` path. Intended for
  downstream crates (e.g. `dashu-ball`) that want by-value `Repr` arithmetic on a
  fixed context. The `+`/`-` operators and `Context::add`/`sub` now route through
  `addsub_*`, making it the single source of truth for add/subtract routing.

### Change
- `x ± 0` now rounds `x` to the context precision. The add/subtract path previously
  short-circuited on a zero operand and returned the other operand verbatim, which
  could leave a guard digit (up to `precision + 1` digits) in the result. All other
  add/subtract results are unchanged.

### Fix
- `test_e_known_decimal_prefix` failed to compile under `no_std` (`ToString` is not in
  the prelude without `std`): import `alloc::string::ToString` in the cache tests.
- `Context::mul`, `Context::sqr`, and `Context::cubic` are now strictly correctly rounded. They
  previously shrank the operand(s) to `2*precision` (mul/sqr) or `3*precision` (cubic) before
  multiplying — a speed optimization. That operand pre-rounding — though each operand is rounded
  correctly — perturbs the result by the accumulated rounding error, so the final value could land
  1 ulp off the exact-product-rounded value when it sat near a rounding boundary. The exact product
  / square / cube of the full operand(s) is now computed and rounded (still via the dedicated
  `sqr`/`cubic` kernels), which is always correctly rounded, at the cost of operating on operands
  far larger than the target precision (uncommon).
- `Display`/`LowerExp`/`UpperExp` (and the per-base `{:b}`/`{:o}`/`{:h}`/`{:x}` formatters) now read
  `Repr::sign` (not the bare significand, which is always `+` for zero) and clamp a zero
  significand's display exponent to `0`, so the `-0` sentinel exponent no longer leaks into the
  output. By default `-0` and `+0` both render as `"0"` (signed zero is treated as an internal
  detail); the formatter's `+` flag reveals the sign (`-0` → `"-0"`, `+0` → `"+0"`) — use it for
  string round-trips (e.g. into MPFR) that must preserve the signed-zero sign.

## 0.5.1

### Add
- `Repr::new_const`: a `const`-evaluable, normalized `Repr` constructor from a `DoubleWord`
  significand (the `const` counterpart of `Repr::new`). `FBig::from_parts_const` now delegates to
  it, and the complex literal macro uses it.
- `FBig::log2` / `Context::log2` / `CachedFBig::log2`: base-2 logarithm, correctly rounded via
  `ln(x)/ln(2)` evaluated at an elevated working precision. Previously only the f32-precision
  `log2_bounds` magnitude estimate was available, so directed `log2` was wrong by many ULPs.

### Fix
- `powi`'s overflow guard no longer reports a spurious overflow when the base is very close to 1
  (a large significand with a large negative exponent). It estimated `log2(base)` with `log2_est`,
  which for such a base is the difference of two ~1e3-magnitude terms and catastrophically cancels
  to ~1e-4 of `f32` noise; scaled by a large exponent that noise crossed the overflow threshold
  — which on 32-bit targets is only `isize::MAX·log2(B) ≈ 7e9` — and returned a spurious ±inf. This
  made high-precision base conversion (`FBig::with_base`) panic ("arithmetic operations with the
  infinity are not allowed!") on 32-bit targets (wasm32, i686). The guard now uses the
  bit-length-based `log2_bounds`, which does not cancel (#95).
- `to_f64`/`to_f32` now round the source once, directly to the target's precision at its own
  magnitude (fewer than 53/24 bits for subnormals), instead of through a fixed 53/24-bit
  intermediate that re-rounds into the subnormal grid. This removes a 1-ULP double-rounding error
  on subnormal values that sit just past a subnormal halfway.
- `to_f64`/`to_f32` no longer panic in debug builds (nor silently double-round in release) on
  high-precision inputs: the base-changing conversion now pre-shrinks the source significand before
  dividing, upholding `repr_div`'s dividend-width contract (as `Context::div` already does) instead
  of feeding an oversized dividend into the division.
- `exp`, `exp_m1`, `sqrt`, `ln`, and `ln_1p` no longer panic on exact zero/one inputs that carry
  unlimited precision (precision 0), such as `FBig::try_from(0.0)` and the `FBig::ONE`/`ZERO`
  constants. The exact-result shortcuts now run before the limited-precision assertion.
- The `round_fract` debug assertion no longer materializes `B^precision`, which for a sparse sticky
  tail (where `precision` is the exponent gap — e.g. `exp_m1` of a large-magnitude input) could
  exhaust memory in debug builds. It now checks the precondition with `log2` bounds.

## 0.5.0

### Add
- **IEEE-754 signed zero (`-0`)**: operations now produce the sign of zero mandated by the standard
  (e.g. `1 / -inf = -0`, `sqrt(-0) = -0`, `ceil(-0) = -0`, cancellation under round-toward-negative).
  `+0` and `-0` compare equal; `-0.0` round-trips through `f32`/`f64`.
- **New error model**: `FpError` (`InfiniteInput`, `OutOfDomain`, `Indeterminate`, and new
  `Overflow(Sign)`/`Underflow(Sign)`) with `FpResult<T> = Result<Rounded<T>, FpError>`. Infinite
  *outputs* are values inside `Ok` (`1/0 → +inf`, `ln(0) → -inf`, `exp(huge) → +inf`); infinite
  *inputs* are `Err(InfiniteInput)` (structurally avoiding NaN-producing indeterminate forms); domain
  errors (`0/0`, `sqrt(-x)`, `ln(-x)`, `asin(|x|>1)`) are `Err`. The `FBig`/`CachedFBig` convenience
  layers panic on error and saturate `Overflow`/`Underflow` to signed infinity/zero.
- **`ConstCache` + `CachedFBig`**: `ConstCache` caches exact binary-splitting tree state for constants
  (π, ln2, ln10, ln(B) — including the base-free `√10005` isqrt that feeds π) so repeated calls at
  increasing precision *extend* prior work instead of recomputing. `CachedFBig` is an `FBig` carrying a
  shared `Rc<RefCell<ConstCache>>` handle; its transcendentals (`ln`, `exp`, `sin`/`cos`/…, `pi`, base
  conversion) thread that handle through `Context`. `Context`/`FBig` stay `Copy` + `Send` + `Sync` +
  `no_std`; only `CachedFBig` is `!Send + !Sync`. `CachedFBig::cache()`/`clear_cache()` and
  `ConstCache::total_terms()`/`total_words()` inspect/free cached memory.
- **Hyperbolic functions** `sinh`/`cosh`/`tanh`/`asinh`/`acosh`/`atanh` on `Context`/`FBig`/`CachedFBig`,
  built from cancellation-free `exp_m1`/`ln_1p` formulas with IEEE special-value handling.
- **`FBig::hypot`** / `Context::hypot`: overflow/underflow-safe `sqrt(a² + b²)` via the scaled
  sum-of-squares (the larger operand is never squared).
- **`FBig::sinh_cosh`** / `Context::sinh_cosh`: combined `sinh`+`cosh` sharing the `exp_m1(±x)` work.
- `exp`/`exp_m1` now accept infinite input (`exp(+inf) = +inf`, `exp(-inf) = +0`, `exp_m1(-inf) = -1`).
- `CachedFBig` now mirrors `FBig`'s full trait surface — formatting, ordering, conversions, shift and
  root/euclid ops, `Sum`/`Product` — plus the reference-operand variants of its binary operators and
  mixed ops with `FBig` and the integer primitives. Third-party traits (serde/num-traits/num-order/
  rand/zeroize/postgres) are reached via `.as_fbig()`.
- `Repr::num_hash_residue` (behind `num-order`), exposed so composite types can combine their parts'
  residues algebraically.

### Change
- **(breaking)** `Repr::is_zero` is renamed to `Repr::is_pos_zero` (it tests only `+0`); use
  `significand().is_zero()` to detect either signed zero. `num_traits::Zero::is_zero` for `FBig` now
  returns `true` for either.
- **(breaking)** `Sum` for `FBig` is now correctly-rounded: addends are accumulated exactly and the
  total rounded once (MPFR `mpfr_sum` semantics). The generic `Sum<T>`/`Product<T>` impls are replaced
  by concrete `Sum`/`Sum<&FBig>`/`Product`/`Product<&FBig>`; cross-type sums (e.g. `Sum<u8>`) require
  converting the elements first.
- **(breaking)** `FBig` human-readable serde now pads the serialized string to the context precision's
  digit count so precision round-trips (the binary format already preserved it).
- **(breaking, encoding)** infinities are re-encoded with sentinel exponents `isize::MAX`/`isize::MIN`
  and `-0` at exponent `-1`; `normalize()` preserves these, and `Repr`'s `PartialEq`/`Eq` are manual
  so `+0 == -0`.
- **(breaking, result model)** `Context` arithmetic/transcendental/trig methods now return
  `FpResult<FBig<R, B>>` instead of `Rounded<FBig<R, B>>` (arithmetic) / the old trig `FpResult` enum.
  `FBig::tan`/`asin`/`acos`/`atan2` now return `Self` (panic on error), matching the other trig methods.
- **(breaking, low-level)** `Context` constant-source methods take an additional
  `cache: Option<&mut ConstCache>` parameter; the high-level `FBig` API is unchanged (passes `None`).
- `atan2(±finite, +inf)` returns the signed zero of `y`; `powf(±0, y)` returns the *positive* result
  (`+0` for `y > 0`, `+inf` for `y < 0`) — use `powi` for the sign-correct `pow(-0, odd) = -0`.

### Remove
- Public `Repr::from_str_native` / `FBig::from_str_native` (now crate-private — use `s.parse()`).
- The old `FpResult` enum and the `MathCache` type (subsumed by the public `ConstCache`).
- The `panic_overflow`/`panic_underflow`/`panic_infinite`/`panic_power_negative_base`/`panic_root_negative`
  helpers (their conditions are now `FpError`s).

### Fix
- Signed-zero correctness: `exp_m1(-0) = -0`; `powf(base, -0) = 1`; `quantize(-0)` preserves the sign;
  `+`/`-` produce `-0` on exact cancellation under `Down`; `Sum` cancellation to zero yields `+0` (or
  `-0` only under roundTowardNegative); `IBig`/`UBig::try_from(FBig)` accept `-0`.
- `NumOrd` against a primitive `0.0`/`-0.0` now reports either signed zero as `Equal`.
- `error_bounds` honors the `ErrorBounds` contract for unlimited precision (`Away` returns
  `(0, 0, true, true)`), and `HalfEven` gives `-0` the one-sided preimage (matching `Zero`/`HalfAway`).
- `Context::asin`/`acos` no longer panic on `±1` under `Down` (the `1 - x²` → `-0` → `sqrt(-0)` path).
- `exp`/`exp_m1`/`powi` return `±inf`/`0` on astronomically large results instead of panicking.
- `exp`/`exp_m1` at high precision (≳ a few thousand digits) were wrong in the low bits — the series
  working precision now carries `≈ √p` extra guard digits to absorb the `Bⁿ` final-powering error
  amplification (cf. MPFR's `K ≈ √precy`).
- `ShrAssign` (`>>=`) previously subtracted the shift twice.
- Trig functions no longer panic on tiny negative inputs (`sin(-1e-30)`): the signed-zero encoding no
  longer trips argument reduction.
- Broken intra-doc links surfaced by `cargo doc -D warnings`; `f64::ceil` in `ConstCache` replaced
  with a `no_std`-safe integer ceiling.
- `FBig::from_repr`'s debug assertion now accepts the documented single guard digit.

### Improve
- Documented the `math::trig` module and enabled `#![deny(missing_docs)]` together with
  `clippy::dbg_macro`, `clippy::undocumented_unsafe_blocks`, and `clippy::let_underscore_must_use`
  as crate-level denies.
- Migrated the verbose `FBig` type prose out of the rustdoc and into the user guide, leaving a concise
  summary with guide links; the runnable `# Examples` are kept verbatim.
- (internal) `Context::iacoth` and the `ConstCache` π path use binary splitting; the PostgreSQL
  `NUMERIC` conversion and trig argument reduction use `UBig::to_digits` / `IBig::try_from`.

## 0.4.5

### Add
- Add `FBig::quantize(exp)` to round to the nearest multiple of `BASE^exp` (the dashu analog of Python's `Decimal.quantize()`), returning `Rounded<Self>` with the result precision set so that `ulp()` equals `BASE^exp`.
- Implement the cubic root (`CubicRoot` for `FBig`, `Context::cbrt`) and the general nth root (`FBig::nth_root`, `Context::nth_root`) with correct rounding, built on top of `UBig::nth_root`.
- Implement trigonometric functions (`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sin_cos`) for `FBig` and `Context<R>` ([#60]https://github.com/cmpute/dashu/pull/60).
- Add π constant computation (`FBig::pi()` and `Context::pi()`) using the Chudnovsky algorithm with binary splitting ([#60]https://github.com/cmpute/dashu/pull/60).
- Add `FpResult` enum to handle non-finite math operation results (NaN, Infinite, Overflow, Underflow) without panicking ([#60]https://github.com/cmpute/dashu/pull/60).
- Add `panic_nan`, `panic_overflow`, `panic_underflow`, and `panic_infinite` helpers to the `error` module.
- Optional `rand_v09` (rand 0.9, MSRV 1.63) and `rand_v010` (rand 0.10, MSRV 1.85) features mirroring `rand_v08`. The default `rand` feature still maps to `rand_v08`.
- The random-float distributions (`Uniform01`, `UniformFBig`) and their sampling now live once in the version-agnostic `dashu_float::rand` module. The per-version modules are now private trait bindings.

### Fix
- Fix rounding issues in `to_f32()` and `to_f64()` ([#53]https://github.com/cmpute/dashu/issues/53, [#56]https://github.com/cmpute/dashu/issues/56).
- Fix several rounding bugs in `FBig`/`Context` addition and subtraction: severe-cancellation collapse, spurious-ULP errors from negligible operands, the window-edge boundary, and `Context::sub` with a zero left operand under directed rounding modes.
- Fix `FBig::fract()` inflating context precision and `split_at_point_internal` using an incorrect fractional scale for values smaller than one.

## 0.4.4

- Bump MSRV from 1.61 to 1.68.

## 0.4.3

- Mark `FBig::from_str_native` as deprecated.
- Implement `TryFrom<Repr>` and `TryFrom<FBig>` for primitive integers.
- Implement `TryFrom<Repr<2>>` and `TryFrom<FBig<_, 2>>` for primitive floats.
- Implement `From<UBig>` and `From<IBig>` for `Repr`.
- Implement `core::fmt::{Binary, Oct, LowerExp, UpperExp, LowerHex, UpperHex}` for `Repr`, `FBig` (some are limited to certain bases).

## 0.4.2

- Add `Repr::from_static_words` to support the `static_fbig!` and `static_dbig!` macros.
- Add `FBig::from_repr_const` to support create an `FBig` instance from repr in const context.
- Add conversion from `f32`/`f64` to `Repr<2>`.
- Implement `NumOrd` between `FBig` and primitive integers / floats. 
- Implement `AbsOrd` between `FBig` and `UBig`/`IBig`.
- Now the `Debug` output of `FBig` values will not contains the rounding mode information (when alternative flag is not set).

## 0.4.1

- Fix the termination criteria for `ln` and `exp` series ([#44]https://github.com/cmpute/dashu/issues/44).
- Fix `powf` panicking when base is 0.

## 0.4.0

### Add

- Implement `num-order::NumOrd` between `FBig` and `UBig`/`IBig` and between `FBig` with different bases.
- Implement `num-order::NumHash` for `FBig` and `Repr`.
- Add `ErrorBounds` trait that calculate the rounding range for a floating point number.

### Change

- Now feature `num-traits` and `rand` are not enabled by default, feature `num-order` is enabled instead.
- The type of `Repr::BASE` is changed from `IBig` to `UBig`
- `UBig::square` and `IBig::square` are renamed to `sqr`.
- The implementation of square root is now implemented by the `dashu_base::SquareRoot` trait instead of a standalone method of `FBig`.
- The rounding behaviors of `FBig::to_decimal` and `FBig::to_binary` are changed for better ergonomics.
- The rounding behaviors of `FBig::to_f32` and `FBig::to_f64` now follow the mode specified by the type argument.

## 0.3.2

- The default precision for float numbers from `from_parts`/`From<UBig>`/`From<IBig>` are now based on the actual digits on the integers, rather than the digits after simplification. (#28)

## 0.3.1

- Implement `num_traits::{Zero, One, FromPrimitive, ToPrimitive, Num, Signed, Euclid, Pow}` for `FBig` (#19)
- Implement `rand::distributions::uniform::UniformSampler` for `FBig` through `crate::rand::UniformFBig`
- Implement `rand::distributions::{Open01, OpenClosed01, Standard}` for `FBig`
- Implement `dashu_base::Inverse` for `FBig`
- Implement `rand::distributions::uniform::SampleUniform` for `FBig`.
- Implement `serde::{Serialize, Deserialize}` for `FBig` and `Repr`
- Implement `Rem` trait for `FBig`
- Add support of random floating point numbers generation through `crate::rand::Uniform01` and `crate::rand::UniformFBig`.
- Add support for serialization from/to PostgreSQL arguments through `diesel::{deserialize::FromSql, serialize::ToSql}` and `postgres_types::{FromSql, ToSql}`.
- Add `from_str_native()` for `Repr`
- Add `to_f32()`, `to_f64()` for `Repr`, and these two methods supports all bases for both `Repr` and `FBig`.
- Add `to_int()` for `Repr`, which is equivalent to `FBig::trunc()`
- Add `TryFrom<FBig>` for `UBig` and `IBig`
- Add `round()` for `FBig`
- Add `rand_v08` and `num-traits_v02` feature flags to prevent breaking changes due to dependency updates in future 
- Re-export operation traits through the `ops` module.

## 0.3.0

### Add

- Conversion from FBig to `f32`/`f64` support subnormal values now.
- Add a `split_at_point()` function to `FBig`

## 0.2.1

- Implement `core::iter::{Sum, Product}` for `FBig`
- Implement `powf`, `sqrt` for `FBig`

## 0.2.0 (Initial release)

- Support basic arithmetic operations (`add`/`sub`/`mul`/`div`/`exp`/`ln`) and base conversion.

# Todo

## Roadmap to next version
- Support generating base math constants (E, Pi, SQRT2, etc.)
- Support operations with inf
- Create operations benchmark
- Benchmark against crates: rug, twofloat, num-bigfloat, rust_decimal, bigdecimal, scientific
- Implement more formatting traits
- Other math functions: sin/cos/tan/etc.