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
13pub mod to_fixed;
14pub use to_fixed::format64_to_fixed;
15
16#[must_use]
54#[cfg_attr(feature = "no-panic", no_panic)]
55pub unsafe fn format64(f: f64, result: *mut u8) -> usize {
56 debug_assert!(!result.is_null());
57
58 let bits = f.to_bits();
59 let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
60 let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1);
61 let ieee_exponent =
62 (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
63
64 if ieee_exponent == 0 && ieee_mantissa == 0 {
65 *result = b'0';
66 return 1;
67 }
68
69 let mut index = 0isize;
70 if sign {
71 *result = b'-';
72 index += 1;
73 }
74
75 let v = d2d(ieee_mantissa, ieee_exponent);
76
77 let length = d2s::decimal_length17(v.mantissa) as isize;
78 let k = v.exponent as isize;
79 let kk = length + k; debug_assert!(k >= -324);
81
82 if 0 <= k && kk <= 21 {
83 write_mantissa_long(v.mantissa, result.offset(index + length));
85 for i in length..kk {
86 *result.offset(index + i) = b'0';
87 }
88 index as usize + kk as usize
89 } else if 0 < kk && kk <= 21 {
90 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
92 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
93 *result.offset(index + kk) = b'.';
94 index as usize + length as usize + 1
95 } else if -6 < kk && kk <= 0 {
96 *result.offset(index) = b'0';
98 *result.offset(index + 1) = b'.';
99 let offset = 2 - kk;
100 for i in 2..offset {
101 *result.offset(index + i) = b'0';
102 }
103 write_mantissa_long(v.mantissa, result.offset(index + length + offset));
104 index as usize + length as usize + offset as usize
105 } else if length == 1 {
106 *result.offset(index) = b'0' + v.mantissa as u8;
108 *result.offset(index + 1) = b'e';
109 index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2))
110 } else {
111 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
113 *result.offset(index) = *result.offset(index + 1);
114 *result.offset(index + 1) = b'.';
115 *result.offset(index + length + 1) = b'e';
116 index as usize
117 + length as usize
118 + 2
119 + write_exponent3(kk - 1, result.offset(index + length + 2))
120 }
121}
122
123#[must_use]
161#[cfg_attr(feature = "no-panic", no_panic)]
162pub unsafe fn format32(f: f32, result: *mut u8) -> usize {
163 debug_assert!(!result.is_null());
164
165 let bits = f.to_bits();
166 let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
167 let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1);
168 let ieee_exponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1);
169
170 if ieee_exponent == 0 && ieee_mantissa == 0 {
171 *result = b'0';
172 return 1;
173 }
174
175 let mut index = 0isize;
176 if sign {
177 *result = b'-';
178 index += 1;
179 }
180
181 let v = f2d(ieee_mantissa, ieee_exponent);
182
183 let length = common::decimal_length9(v.mantissa) as isize;
184 let k = v.exponent as isize;
185 let kk = length + k; debug_assert!(k >= -45);
187
188 if 0 <= k && kk <= 21 {
189 write_mantissa(v.mantissa, result.offset(index + length));
191 for i in length..kk {
192 *result.offset(index + i) = b'0';
193 }
194 index as usize + kk as usize
195 } else if 0 < kk && kk <= 21 {
196 write_mantissa(v.mantissa, result.offset(index + length + 1));
198 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
199 *result.offset(index + kk) = b'.';
200 index as usize + length as usize + 1
201 } else if -6 < kk && kk <= 0 {
202 *result.offset(index) = b'0';
204 *result.offset(index + 1) = b'.';
205 let offset = 2 - kk;
206 for i in 2..offset {
207 *result.offset(index + i) = b'0';
208 }
209 write_mantissa(v.mantissa, result.offset(index + length + offset));
210 index as usize + length as usize + offset as usize
211 } else if length == 1 {
212 *result.offset(index) = b'0' + v.mantissa as u8;
214 *result.offset(index + 1) = b'e';
215 index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
216 } else {
217 write_mantissa(v.mantissa, result.offset(index + length + 1));
219 *result.offset(index) = *result.offset(index + 1);
220 *result.offset(index + 1) = b'.';
221 *result.offset(index + length + 1) = b'e';
222 index as usize
223 + length as usize
224 + 2
225 + write_exponent2(kk - 1, result.offset(index + length + 2))
226 }
227}