ryu/pretty/
mod.rs
1mod exponent;
2mod mantissa;
3
4use core::{mem, ptr};
5
6use self::exponent::*;
7use self::mantissa::*;
8use common;
9use d2s;
10use d2s::*;
11use f2s::*;
12
13#[cfg(feature = "no-panic")]
14use no_panic::no_panic;
15
16#[cfg_attr(must_use_return, must_use)]
54#[cfg_attr(feature = "no-panic", no_panic)]
55pub unsafe fn format64(f: f64, result: *mut u8) -> usize {
56 let bits = mem::transmute::<f64, u64>(f);
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 =
60 (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1);
61
62 let mut index = 0isize;
63 if sign {
64 *result = b'-';
65 index += 1;
66 }
67
68 if ieee_exponent == 0 && ieee_mantissa == 0 {
69 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
70 return sign as usize + 3;
71 }
72
73 let v = d2d(ieee_mantissa, ieee_exponent);
74
75 let length = d2s::decimal_length17(v.mantissa) as isize;
76 let k = v.exponent as isize;
77 let kk = length + k; debug_assert!(k >= -324);
79
80 if 0 <= k && kk <= 16 {
81 write_mantissa_long(v.mantissa, result.offset(index + length));
83 for i in length..kk {
84 *result.offset(index + i) = b'0';
85 }
86 *result.offset(index + kk) = b'.';
87 *result.offset(index + kk + 1) = b'0';
88 index as usize + kk as usize + 2
89 } else if 0 < kk && kk <= 16 {
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 -5 < 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#[cfg_attr(must_use_return, must_use)]
161#[cfg_attr(feature = "no-panic", no_panic)]
162pub unsafe fn format32(f: f32, result: *mut u8) -> usize {
163 let bits = mem::transmute::<f32, u32>(f);
164 let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0;
165 let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1);
166 let ieee_exponent =
167 ((bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1)) as u32;
168
169 let mut index = 0isize;
170 if sign {
171 *result = b'-';
172 index += 1;
173 }
174
175 if ieee_exponent == 0 && ieee_mantissa == 0 {
176 ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3);
177 return sign as usize + 3;
178 }
179
180 let v = f2d(ieee_mantissa, ieee_exponent);
181
182 let length = common::decimal_length9(v.mantissa) as isize;
183 let k = v.exponent as isize;
184 let kk = length + k; debug_assert!(k >= -45);
186
187 if 0 <= k && kk <= 13 {
188 write_mantissa(v.mantissa, result.offset(index + length));
190 for i in length..kk {
191 *result.offset(index + i) = b'0';
192 }
193 *result.offset(index + kk) = b'.';
194 *result.offset(index + kk + 1) = b'0';
195 index as usize + kk as usize + 2
196 } else if 0 < kk && kk <= 13 {
197 write_mantissa(v.mantissa, result.offset(index + length + 1));
199 ptr::copy(result.offset(index + 1), result.offset(index), kk as usize);
200 *result.offset(index + kk) = b'.';
201 index as usize + length as usize + 1
202 } else if -6 < kk && kk <= 0 {
203 *result.offset(index) = b'0';
205 *result.offset(index + 1) = b'.';
206 let offset = 2 - kk;
207 for i in 2..offset {
208 *result.offset(index + i) = b'0';
209 }
210 write_mantissa(v.mantissa, result.offset(index + length + offset));
211 index as usize + length as usize + offset as usize
212 } else if length == 1 {
213 *result.offset(index) = b'0' + v.mantissa as u8;
215 *result.offset(index + 1) = b'e';
216 index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2))
217 } else {
218 write_mantissa(v.mantissa, result.offset(index + length + 1));
220 *result.offset(index) = *result.offset(index + 1);
221 *result.offset(index + 1) = b'.';
222 *result.offset(index + length + 1) = b'e';
223 index as usize
224 + length as usize
225 + 2
226 + write_exponent2(kk - 1, result.offset(index + length + 2))
227 }
228}