Coverage Report

Created: 2025-07-11 06:21

/rust/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.20/src/pretty/mod.rs
Line
Count
Source (jump to first uncovered line)
1
mod exponent;
2
mod mantissa;
3
4
use self::exponent::{write_exponent2, write_exponent3};
5
use self::mantissa::{write_mantissa, write_mantissa_long};
6
use crate::common;
7
use crate::d2s::{self, d2d, DOUBLE_EXPONENT_BITS, DOUBLE_MANTISSA_BITS};
8
use crate::f2s::{f2d, FLOAT_EXPONENT_BITS, FLOAT_MANTISSA_BITS};
9
use core::ptr;
10
#[cfg(feature = "no-panic")]
11
use no_panic::no_panic;
12
13
/// Print f64 to the given buffer and return number of bytes written.
14
///
15
/// At most 24 bytes will be written.
16
///
17
/// ## Special cases
18
///
19
/// This function **does not** check for NaN or infinity. If the input
20
/// number is not a finite float, the printed representation will be some
21
/// correctly formatted but unspecified numerical value.
22
///
23
/// Please check [`is_finite`] yourself before calling this function, or
24
/// check [`is_nan`] and [`is_infinite`] and handle those cases yourself.
25
///
26
/// [`is_finite`]: f64::is_finite
27
/// [`is_nan`]: f64::is_nan
28
/// [`is_infinite`]: f64::is_infinite
29
///
30
/// ## Safety
31
///
32
/// The `result` pointer argument must point to sufficiently many writable bytes
33
/// to hold Ryū's representation of `f`.
34
///
35
/// ## Example
36
///
37
/// ```
38
/// use std::{mem::MaybeUninit, slice, str};
39
///
40
/// let f = 1.234f64;
41
///
42
/// unsafe {
43
///     let mut buffer = [MaybeUninit::<u8>::uninit(); 24];
44
///     let len = ryu::raw::format64(f, buffer.as_mut_ptr() as *mut u8);
45
///     let slice = slice::from_raw_parts(buffer.as_ptr() as *const u8, len);
46
///     let print = str::from_utf8_unchecked(slice);
47
///     assert_eq!(print, "1.234");
48
/// }
49
/// ```
50
#[must_use]
51
#[cfg_attr(feature = "no-panic", no_panic)]
52
1.16k
pub unsafe fn format64(f: f64, result: *mut u8) -> usize {
53
1.16k
    let bits = f.to_bits();
54
1.16k
    let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
55
1.16k
    let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1);
56
1.16k
    let ieee_exponent =
57
1.16k
        (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
58
1.16k
59
1.16k
    let mut index = 0isize;
60
1.16k
    if sign {
61
17
        *result = b'-';
62
17
        index += 1;
63
1.15k
    }
64
65
1.16k
    if ieee_exponent == 0 && ieee_mantissa == 0 {
66
6
        ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
67
6
        return sign as usize + 3;
68
1.16k
    }
69
1.16k
70
1.16k
    let v = d2d(ieee_mantissa, ieee_exponent);
71
1.16k
72
1.16k
    let length = d2s::decimal_length17(v.mantissa) as isize;
73
1.16k
    let k = v.exponent as isize;
74
1.16k
    let kk = length + k; // 10^(kk-1) <= v < 10^kk
75
1.16k
    debug_assert!(k >= -324);
76
77
1.16k
    if 0 <= k && kk <= 16 {
78
        // 1234e7 -> 12340000000.0
79
367
        write_mantissa_long(v.mantissa, result.offset(index + length));
80
367
        for i in length..kk {
81
160
            *result.offset(index + i) = b'0';
82
160
        }
83
367
        *result.offset(index + kk) = b'.';
84
367
        *result.offset(index + kk + 1) = b'0';
85
367
        index as usize + kk as usize + 2
86
796
    } else if 0 < kk && kk <= 16 {
87
        // 1234e-2 -> 12.34
88
284
        write_mantissa_long(v.mantissa, result.offset(index + length + 1));
89
284
        ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
90
284
        *result.offset(index + kk) = b'.';
91
284
        index as usize + length as usize + 1
92
512
    } else if -5 < kk && kk <= 0 {
93
        // 1234e-6 -> 0.001234
94
248
        *result.offset(index) = b'0';
95
248
        *result.offset(index + 1) = b'.';
96
248
        let offset = 2 - kk;
97
248
        for i in 2..offset {
98
21
            *result.offset(index + i) = b'0';
99
21
        }
100
248
        write_mantissa_long(v.mantissa, result.offset(index + length + offset));
101
248
        index as usize + length as usize + offset as usize
102
264
    } else if length == 1 {
103
        // 1e30
104
103
        *result.offset(index) = b'0' + v.mantissa as u8;
105
103
        *result.offset(index + 1) = b'e';
106
103
        index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2))
107
    } else {
108
        // 1234e30 -> 1.234e33
109
161
        write_mantissa_long(v.mantissa, result.offset(index + length + 1));
110
161
        *result.offset(index) = *result.offset(index + 1);
111
161
        *result.offset(index + 1) = b'.';
112
161
        *result.offset(index + length + 1) = b'e';
113
161
        index as usize
114
161
            + length as usize
115
161
            + 2
116
161
            + write_exponent3(kk - 1, result.offset(index + length + 2))
117
    }
118
1.16k
}
119
120
/// Print f32 to the given buffer and return number of bytes written.
121
///
122
/// At most 16 bytes will be written.
123
///
124
/// ## Special cases
125
///
126
/// This function **does not** check for NaN or infinity. If the input
127
/// number is not a finite float, the printed representation will be some
128
/// correctly formatted but unspecified numerical value.
129
///
130
/// Please check [`is_finite`] yourself before calling this function, or
131
/// check [`is_nan`] and [`is_infinite`] and handle those cases yourself.
132
///
133
/// [`is_finite`]: f32::is_finite
134
/// [`is_nan`]: f32::is_nan
135
/// [`is_infinite`]: f32::is_infinite
136
///
137
/// ## Safety
138
///
139
/// The `result` pointer argument must point to sufficiently many writable bytes
140
/// to hold Ryū's representation of `f`.
141
///
142
/// ## Example
143
///
144
/// ```
145
/// use std::{mem::MaybeUninit, slice, str};
146
///
147
/// let f = 1.234f32;
148
///
149
/// unsafe {
150
///     let mut buffer = [MaybeUninit::<u8>::uninit(); 16];
151
///     let len = ryu::raw::format32(f, buffer.as_mut_ptr() as *mut u8);
152
///     let slice = slice::from_raw_parts(buffer.as_ptr() as *const u8, len);
153
///     let print = str::from_utf8_unchecked(slice);
154
///     assert_eq!(print, "1.234");
155
/// }
156
/// ```
157
#[must_use]
158
#[cfg_attr(feature = "no-panic", no_panic)]
159
0
pub unsafe fn format32(f: f32, result: *mut u8) -> usize {
160
0
    let bits = f.to_bits();
161
0
    let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
162
0
    let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1);
163
0
    let ieee_exponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1);
164
0
165
0
    let mut index = 0isize;
166
0
    if sign {
167
0
        *result = b'-';
168
0
        index += 1;
169
0
    }
170
171
0
    if ieee_exponent == 0 && ieee_mantissa == 0 {
172
0
        ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
173
0
        return sign as usize + 3;
174
0
    }
175
0
176
0
    let v = f2d(ieee_mantissa, ieee_exponent);
177
0
178
0
    let length = common::decimal_length9(v.mantissa) as isize;
179
0
    let k = v.exponent as isize;
180
0
    let kk = length + k; // 10^(kk-1) <= v < 10^kk
181
0
    debug_assert!(k >= -45);
182
183
0
    if 0 <= k && kk <= 13 {
184
        // 1234e7 -> 12340000000.0
185
0
        write_mantissa(v.mantissa, result.offset(index + length));
186
0
        for i in length..kk {
187
0
            *result.offset(index + i) = b'0';
188
0
        }
189
0
        *result.offset(index + kk) = b'.';
190
0
        *result.offset(index + kk + 1) = b'0';
191
0
        index as usize + kk as usize + 2
192
0
    } else if 0 < kk && kk <= 13 {
193
        // 1234e-2 -> 12.34
194
0
        write_mantissa(v.mantissa, result.offset(index + length + 1));
195
0
        ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
196
0
        *result.offset(index + kk) = b'.';
197
0
        index as usize + length as usize + 1
198
0
    } else if -6 < kk && kk <= 0 {
199
        // 1234e-6 -> 0.001234
200
0
        *result.offset(index) = b'0';
201
0
        *result.offset(index + 1) = b'.';
202
0
        let offset = 2 - kk;
203
0
        for i in 2..offset {
204
0
            *result.offset(index + i) = b'0';
205
0
        }
206
0
        write_mantissa(v.mantissa, result.offset(index + length + offset));
207
0
        index as usize + length as usize + offset as usize
208
0
    } else if length == 1 {
209
        // 1e30
210
0
        *result.offset(index) = b'0' + v.mantissa as u8;
211
0
        *result.offset(index + 1) = b'e';
212
0
        index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
213
    } else {
214
        // 1234e30 -> 1.234e33
215
0
        write_mantissa(v.mantissa, result.offset(index + length + 1));
216
0
        *result.offset(index) = *result.offset(index + 1);
217
0
        *result.offset(index + 1) = b'.';
218
0
        *result.offset(index + length + 1) = b'e';
219
0
        index as usize
220
0
            + length as usize
221
0
            + 2
222
0
            + write_exponent2(kk - 1, result.offset(index + length + 2))
223
    }
224
0
}