1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// Translated from C to Rust. The original C code can be found at // https://github.com/ulfjack/ryu and carries the following license: // // Copyright 2018 Ulf Adams // // The contents of this file may be used under the terms of the Apache License, // Version 2.0. // // (See accompanying file LICENSE-Apache or copy at // http://www.apache.org/licenses/LICENSE-2.0) // // Alternatively, the contents of this file may be used under the terms of // the Boost Software License, Version 1.0. // (See accompanying file LICENSE-Boost or copy at // https://www.boost.org/LICENSE_1_0.txt) // // Unless required by applicable law or agreed to in writing, this software // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. use core::ptr; // Returns e == 0 ? 1 : ceil(log_2(5^e)). #[cfg_attr(feature = "no-panic", inline)] pub fn pow5bits(e: i32) -> u32 { // This approximation works up to the point that the multiplication overflows at e = 3529. // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater // than 2^9297. debug_assert!(e >= 0); debug_assert!(e <= 3528); ((e as u32 * 1217359) >> 19) + 1 } // Returns floor(log_10(2^e)). #[cfg_attr(feature = "no-panic", inline)] pub fn log10_pow2(e: i32) -> i32 { // The first value this approximation fails for is 2^1651 which is just greater than 10^297. debug_assert!(e >= 0); debug_assert!(e <= 1650); ((e as u32 * 78913) >> 18) as i32 } // Returns floor(log_10(5^e)). #[cfg_attr(feature = "no-panic", inline)] pub fn log10_pow5(e: i32) -> i32 { // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. debug_assert!(e >= 0); debug_assert!(e <= 2620); ((e as u32 * 732923) >> 20) as i32 } #[cfg_attr(feature = "no-panic", inline)] pub unsafe fn copy_special_str( result: *mut u8, sign: bool, exponent: bool, mantissa: bool, ) -> usize { if mantissa { ptr::copy_nonoverlapping(b"NaN".as_ptr(), result, 3); return 3; } if sign { *result = b'-'; } if exponent { ptr::copy_nonoverlapping(b"Infinity".as_ptr(), result.offset(sign as isize), 8); return sign as usize + 8; } ptr::copy_nonoverlapping(b"0E0".as_ptr(), result.offset(sign as isize), 3); sign as usize + 3 }