1mod exponent;
2mod mantissa;
3
4use self::exponent::{write_exponent2, write_exponent3};
5use self::mantissa::{write_mantissa, write_mantissa_long};
6use crate::common;
7use crate::d2s::{self, d2d, DOUBLE_EXPONENT_BITS, DOUBLE_MANTISSA_BITS};
8use crate::f2s::{f2d, FLOAT_EXPONENT_BITS, FLOAT_MANTISSA_BITS};
9use core::ptr;
10#[cfg(feature = "no-panic")]
11use no_panic::no_panic;
12
13macro_rules! const_for_in_range_full {
14 (for $i:ident in $range_start:tt..$range_end:tt $body:block) => {{
15 let mut $i = $range_start;
16
17 while $i < $range_end {
18 $body
19 $i += 1;
20 }
21 }};
22}
23
24#[must_use]
62#[cfg_attr(feature = "no-panic", no_panic)]
63pub const unsafe fn format64(f: f64, result: *mut u8) -> usize {
64 let bits = f.to_bits();
65 let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
66 let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1);
67 let ieee_exponent =
68 (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
69
70 let mut index = 0isize;
71 if sign {
72 *result = b'-';
73 index += 1;
74 }
75
76 if ieee_exponent == 0 && ieee_mantissa == 0 {
77 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
78 return sign as usize + 3;
79 }
80
81 let v = d2d(ieee_mantissa, ieee_exponent);
82
83 let length = d2s::decimal_length17(v.mantissa) as isize;
84 let k = v.exponent as isize;
85 let kk = length + k; if true {
if !(k >= -324) {
::core::panicking::panic("assertion failed: k >= -324")
};
};debug_assert!(k >= -324);
87
88 if 0 <= k && kk <= 16 {
89 write_mantissa_long(v.mantissa, result.offset(index + length));
91
92 {
let mut i = length;
while i < kk { { *result.offset(index + i) = b'0'; } i += 1; }
}const_for_in_range_full! {
93 for i in length..kk {
94 *result.offset(index + i) = b'0';
95 }
96 }
97
98 *result.offset(index + kk) = b'.';
99 *result.offset(index + kk + 1) = b'0';
100 index as usize + kk as usize + 2
101 } else if 0 < kk && kk <= 16 {
102 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
104 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
105 *result.offset(index + kk) = b'.';
106 index as usize + length as usize + 1
107 } else if -5 < kk && kk <= 0 {
108 *result.offset(index) = b'0';
110 *result.offset(index + 1) = b'.';
111 let offset = 2 - kk;
112
113 {
let mut i = 2;
while i < offset { { *result.offset(index + i) = b'0'; } i += 1; }
}const_for_in_range_full! {
114 for i in 2..offset {
115 *result.offset(index + i) = b'0';
116 }
117 }
118
119 write_mantissa_long(v.mantissa, result.offset(index + length + offset));
120 index as usize + length as usize + offset as usize
121 } else if length == 1 {
122 *result.offset(index) = b'0' + v.mantissa as u8;
124 *result.offset(index + 1) = b'e';
125 index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2))
126 } else {
127 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
129 *result.offset(index) = *result.offset(index + 1);
130 *result.offset(index + 1) = b'.';
131 *result.offset(index + length + 1) = b'e';
132 index as usize
133 + length as usize
134 + 2
135 + write_exponent3(kk - 1, result.offset(index + length + 2))
136 }
137}
138
139#[must_use]
177#[cfg_attr(feature = "no-panic", no_panic)]
178pub const unsafe fn format32(f: f32, result: *mut u8) -> usize {
179 let bits = f.to_bits();
180 let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
181 let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1);
182 let ieee_exponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1);
183
184 let mut index = 0isize;
185 if sign {
186 *result = b'-';
187 index += 1;
188 }
189
190 if ieee_exponent == 0 && ieee_mantissa == 0 {
191 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
192 return sign as usize + 3;
193 }
194
195 let v = f2d(ieee_mantissa, ieee_exponent);
196
197 let length = common::decimal_length9(v.mantissa) as isize;
198 let k = v.exponent as isize;
199 let kk = length + k; if true {
if !(k >= -45) { ::core::panicking::panic("assertion failed: k >= -45") };
};debug_assert!(k >= -45);
201
202 if 0 <= k && kk <= 13 {
203 write_mantissa(v.mantissa, result.offset(index + length));
205
206 {
let mut i = length;
while i < kk { { *result.offset(index + i) = b'0'; } i += 1; }
}const_for_in_range_full! {
207 for i in length..kk {
208 *result.offset(index + i) = b'0';
209 }
210 }
211
212 *result.offset(index + kk) = b'.';
213 *result.offset(index + kk + 1) = b'0';
214 index as usize + kk as usize + 2
215 } else if 0 < kk && kk <= 13 {
216 write_mantissa(v.mantissa, result.offset(index + length + 1));
218 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
219 *result.offset(index + kk) = b'.';
220 index as usize + length as usize + 1
221 } else if -6 < kk && kk <= 0 {
222 *result.offset(index) = b'0';
224 *result.offset(index + 1) = b'.';
225 let offset = 2 - kk;
226
227 {
let mut i = 2;
while i < offset { { *result.offset(index + i) = b'0'; } i += 1; }
}const_for_in_range_full! {
228 for i in 2..offset {
229 *result.offset(index + i) = b'0';
230 }
231 }
232
233 write_mantissa(v.mantissa, result.offset(index + length + offset));
234 index as usize + length as usize + offset as usize
235 } else if length == 1 {
236 *result.offset(index) = b'0' + v.mantissa as u8;
238 *result.offset(index + 1) = b'e';
239 index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
240 } else {
241 write_mantissa(v.mantissa, result.offset(index + length + 1));
243 *result.offset(index) = *result.offset(index + 1);
244 *result.offset(index + 1) = b'.';
245 *result.offset(index + length + 1) = b'e';
246 index as usize
247 + length as usize
248 + 2
249 + write_exponent2(kk - 1, result.offset(index + length + 2))
250 }
251}