1mod exponent;
2mod mantissa;
3
4use core::ptr;
5
6use self::{
7 exponent::{write_exponent2, write_exponent3},
8 mantissa::{write_mantissa, write_mantissa_long},
9};
10use crate::{
11 common,
12 d2s::{self, DOUBLE_EXPONENT_BITS, DOUBLE_MANTISSA_BITS, d2d},
13 f2s::{FLOAT_EXPONENT_BITS, FLOAT_MANTISSA_BITS, f2d},
14};
15
16#[must_use]
54pub unsafe fn format64(f: f64, result: *mut u8) -> usize {
55 unsafe {
56 let bits = f.to_bits();
57 let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0;
58 let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1);
59 let ieee_exponent = (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
60
61 let mut index = 0isize;
62 if sign {
63 *result = b'-';
64 index += 1;
65 }
66
67 if ieee_exponent == 0 && ieee_mantissa == 0 {
68 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
69 return sign as usize + 3;
70 }
71
72 let v = d2d(ieee_mantissa, ieee_exponent);
73
74 let length = d2s::decimal_length17(v.mantissa) as isize;
75 let k = v.exponent as isize;
76 let kk = length + k; debug_assert!(k >= -324);
78
79 if 0 <= k && kk <= 16 {
80 write_mantissa_long(v.mantissa, result.offset(index + length));
82 for i in length..kk {
83 *result.offset(index + i) = b'0';
84 }
85 *result.offset(index + kk) = b'.';
86 *result.offset(index + kk + 1) = b'0';
87 index as usize + kk as usize + 2
88 } else if 0 < kk && kk <= 16 {
89 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
91 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
92 *result.offset(index + kk) = b'.';
93 index as usize + length as usize + 1
94 } else if -5 < kk && kk <= 0 {
95 *result.offset(index) = b'0';
97 *result.offset(index + 1) = b'.';
98 let offset = 2 - kk;
99 for i in 2..offset {
100 *result.offset(index + i) = b'0';
101 }
102 write_mantissa_long(v.mantissa, result.offset(index + length + offset));
103 index as usize + length as usize + offset as usize
104 } else if length == 1 {
105 *result.offset(index) = b'0' + v.mantissa as u8;
107 *result.offset(index + 1) = b'e';
108 index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2))
109 } else {
110 write_mantissa_long(v.mantissa, result.offset(index + length + 1));
112 *result.offset(index) = *result.offset(index + 1);
113 *result.offset(index + 1) = b'.';
114 *result.offset(index + length + 1) = b'e';
115 index as usize + length as usize + 2 + write_exponent3(kk - 1, result.offset(index + length + 2))
116 }
117 }
118}
119
120#[must_use]
158pub unsafe fn format32(f: f32, result: *mut u8) -> usize {
159 unsafe {
160 let bits = f.to_bits();
161 let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
162 let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1);
163 let ieee_exponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1);
164
165 let mut index = 0isize;
166 if sign {
167 *result = b'-';
168 index += 1;
169 }
170
171 if ieee_exponent == 0 && ieee_mantissa == 0 {
172 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
173 return sign as usize + 3;
174 }
175
176 let v = f2d(ieee_mantissa, ieee_exponent);
177
178 let length = common::decimal_length9(v.mantissa) as isize;
179 let k = v.exponent as isize;
180 let kk = length + k; debug_assert!(k >= -45);
182
183 if 0 <= k && kk <= 13 {
184 write_mantissa(v.mantissa, result.offset(index + length));
186 for i in length..kk {
187 *result.offset(index + i) = b'0';
188 }
189 *result.offset(index + kk) = b'.';
190 *result.offset(index + kk + 1) = b'0';
191 index as usize + kk as usize + 2
192 } else if 0 < kk && kk <= 13 {
193 write_mantissa(v.mantissa, result.offset(index + length + 1));
195 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
196 *result.offset(index + kk) = b'.';
197 index as usize + length as usize + 1
198 } else if -6 < kk && kk <= 0 {
199 *result.offset(index) = b'0';
201 *result.offset(index + 1) = b'.';
202 let offset = 2 - kk;
203 for i in 2..offset {
204 *result.offset(index + i) = b'0';
205 }
206 write_mantissa(v.mantissa, result.offset(index + length + offset));
207 index as usize + length as usize + offset as usize
208 } else if length == 1 {
209 *result.offset(index) = b'0' + v.mantissa as u8;
211 *result.offset(index + 1) = b'e';
212 index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
213 } else {
214 write_mantissa(v.mantissa, result.offset(index + length + 1));
216 *result.offset(index) = *result.offset(index + 1);
217 *result.offset(index + 1) = b'.';
218 *result.offset(index + length + 1) = b'e';
219 index as usize + length as usize + 2 + write_exponent2(kk - 1, result.offset(index + length + 2))
220 }
221 }
222}