1mod exponent;
2mod mantissa;
3
4use core::ptr;
5
6#[cfg(feature = "no-panic")]
7use no_panic::no_panic;
8
9use self::{
10 exponent::{write_exponent2, write_exponent3},
11 mantissa::{write_mantissa, write_mantissa_long},
12};
13use crate::{
14 common,
15 d2s::{self, DOUBLE_EXPONENT_BITS, DOUBLE_MANTISSA_BITS, d2d},
16 f2s::{FLOAT_EXPONENT_BITS, FLOAT_MANTISSA_BITS, f2d},
17};
18
19#[must_use]
57#[cfg_attr(feature = "no-panic", no_panic)]
58pub unsafe fn format64(f: f64, result: *mut u8) -> usize {
59 unsafe {
60 let bits = f.to_bits();
61 let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
62 let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1);
63 let ieee_exponent = (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
64
65 let mut index = 0isize;
66 if sign {
67 *result = b'-';
68 index += 1;
69 }
70
71 if ieee_exponent == 0 && ieee_mantissa == 0 {
72 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
73 return sign as usize + 3;
74 }
75
76 let v = d2d(ieee_mantissa, ieee_exponent);
77
78 let length = d2s::decimal_length17(v.mantissa) as isize;
79 let k = v.exponent as isize;
80 let kk = length + k; debug_assert!(k >= -324);
82
83 if 0 <= k && kk <= 16 {
84 write_mantissa_long(v.mantissa, result.offset(index + length));
86 for i in length..kk {
87 *result.offset(index + i) = b'0';
88 }
89 *result.offset(index + kk) = b'.';
90 *result.offset(index + kk + 1) = b'0';
91 index as usize + kk as usize + 2
92 } else if 0 < kk && kk <= 16 {
93 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
95 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
96 *result.offset(index + kk) = b'.';
97 index as usize + length as usize + 1
98 } else if -5 < kk && kk <= 0 {
99 *result.offset(index) = b'0';
101 *result.offset(index + 1) = b'.';
102 let offset = 2 - kk;
103 for i in 2..offset {
104 *result.offset(index + i) = b'0';
105 }
106 write_mantissa_long(v.mantissa, result.offset(index + length + offset));
107 index as usize + length as usize + offset as usize
108 } else if length == 1 {
109 *result.offset(index) = b'0' + v.mantissa as u8;
111 *result.offset(index + 1) = b'e';
112 index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2))
113 } else {
114 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
116 *result.offset(index) = *result.offset(index + 1);
117 *result.offset(index + 1) = b'.';
118 *result.offset(index + length + 1) = b'e';
119 index as usize + length as usize + 2 + write_exponent3(kk - 1, result.offset(index + length + 2))
120 }
121 }
122}
123
124#[must_use]
162#[cfg_attr(feature = "no-panic", no_panic)]
163pub unsafe fn format32(f: f32, result: *mut u8) -> usize {
164 unsafe {
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 let mut index = 0isize;
171 if sign {
172 *result = b'-';
173 index += 1;
174 }
175
176 if ieee_exponent == 0 && ieee_mantissa == 0 {
177 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
178 return sign as usize + 3;
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 <= 13 {
189 write_mantissa(v.mantissa, result.offset(index + length));
191 for i in length..kk {
192 *result.offset(index + i) = b'0';
193 }
194 *result.offset(index + kk) = b'.';
195 *result.offset(index + kk + 1) = b'0';
196 index as usize + kk as usize + 2
197 } else if 0 < kk && kk <= 13 {
198 write_mantissa(v.mantissa, result.offset(index + length + 1));
200 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
201 *result.offset(index + kk) = b'.';
202 index as usize + length as usize + 1
203 } else if -6 < kk && kk <= 0 {
204 *result.offset(index) = b'0';
206 *result.offset(index + 1) = b'.';
207 let offset = 2 - kk;
208 for i in 2..offset {
209 *result.offset(index + i) = b'0';
210 }
211 write_mantissa(v.mantissa, result.offset(index + length + offset));
212 index as usize + length as usize + offset as usize
213 } else if length == 1 {
214 *result.offset(index) = b'0' + v.mantissa as u8;
216 *result.offset(index + 1) = b'e';
217 index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
218 } else {
219 write_mantissa(v.mantissa, result.offset(index + length + 1));
221 *result.offset(index) = *result.offset(index + 1);
222 *result.offset(index + 1) = b'.';
223 *result.offset(index + length + 1) = b'e';
224 index as usize + length as usize + 2 + write_exponent2(kk - 1, result.offset(index + length + 2))
225 }
226 }
227}