| 393 | } |
| 394 | |
| 395 | fn fixed(mag: f64, prec: usize) -> String { |
| 396 | // Round-half-to-even to `prec` decimals; renders manually to avoid `alloc::format!`'s %f. |
| 397 | let scale = pow10(prec); |
| 398 | let scaled = mag * scale; |
| 399 | let rounded = if fabs(scaled - ftrunc(scaled)) == 0.5 { |
| 400 | let f = ftrunc(scaled); |
| 401 | if (f as i64) % 2 == 0 { f } else if scaled > 0.0 { f + 1.0 } else { f - 1.0 } |
| 402 | } else { |
| 403 | ftrunc(scaled + 0.5 * fsignum(scaled)) |
| 404 | }; |
| 405 | let dec = u128_to_dec(fabs(rounded) as u128); |
| 406 | if prec == 0 { return dec; } |
| 407 | /* Pad on the left so we can insert a `.` exactly `prec` chars from the end. */ |
| 408 | let needed = prec + 1; |
| 409 | let padded = if dec.len() < needed { |
| 410 | let mut s = String::with_capacity(needed); |
| 411 | for _ in 0..(needed - dec.len()) { s.push('0'); } |
| 412 | s.push_str(&dec); s |
| 413 | } else { dec }; |
| 414 | let dot = padded.len() - prec; |
| 415 | let mut out = String::with_capacity(padded.len() + 1); |
| 416 | out.push_str(&padded[..dot]); |
| 417 | out.push('.'); |
| 418 | out.push_str(&padded[dot..]); |
| 419 | out |
| 420 | } |
| 421 | |
| 422 | fn pow10(n: usize) -> f64 { |
| 423 | let mut r = 1.0f64; |