MAV'RIC
|
00001 /******************************************************************************* 00002 * Copyright (c) 2009-2016, MAV'RIC Development Team 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of the copyright holder nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software without 00017 * specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 ******************************************************************************/ 00031 00032 /******************************************************************************* 00033 * \file string_utils.hxx 00034 * 00035 * \author MAV'RIC Team 00036 * 00037 * \brief Implementation of template functions for string_util 00038 * (see string_util.cpp for non-template implementations) 00039 * 00040 ******************************************************************************/ 00041 00042 #include "util/maths.h" 00043 00044 namespace str 00045 { 00046 00047 template<typename T> 00048 uint8_t* format_integer(T number, uint8_t* dest, uint8_t* length, uint8_t max_digits) 00049 { 00050 uint8_t i = max_digits + 1; 00051 00052 /* Take Care of the sign */ 00053 bool is_negativ = false; 00054 if (number < 0) 00055 { 00056 is_negativ = true; 00057 number = number * -1; 00058 } 00059 00060 do 00061 { 00062 dest[--i] = (number % 10) + '0'; 00063 number = number / 10; 00064 } 00065 while ((i >= 1) && (number > 0)); 00066 00067 /* add sign to char* */ 00068 if (is_negativ) 00069 { 00070 dest[--i] = '-'; 00071 } 00072 00073 *length = max_digits + 1 - i; 00074 00075 return dest + i; 00076 } 00077 00078 00079 template <typename T> 00080 uint8_t* format_floating(T num, uint8_t* dest, uint8_t* length, uint8_t after_digits, uint8_t max_int_digits) 00081 { 00082 bool is_negativ = false; 00083 if (num < 0) 00084 { 00085 is_negativ = true; 00086 num = num * -1; 00087 } 00088 00089 /* write the integer part to char array 'dest' / 'data' */ 00090 int32_t whole = floor(num); 00091 uint8_t i, j; 00092 uint8_t* data = format_integer(whole, dest + 1, &i, max_int_digits); 00093 00094 /* add minus sign to array if needed */ 00095 if (is_negativ) 00096 { 00097 data = data - 1; 00098 data[0] = '-'; 00099 i++; 00100 } 00101 00102 /* get floating point part */ 00103 T after = (num - (T)whole); 00104 00105 data[i++] = '.'; 00106 for (j = 0; j < after_digits; j++) 00107 { 00108 after *= 10; 00109 char digit = (char)after; 00110 data[i++] = digit + '0'; 00111 after = after - digit; 00112 } 00113 00114 /* calc length */ 00115 *length = i; 00116 00117 return data; 00118 } 00119 00120 00121 template <typename T> 00122 uint8_t* format_scientific(T num, uint8_t* dest, uint8_t* length, uint8_t after_digits) 00123 { 00124 // Determine if the number is less than or equal to 1 or 00125 // greater than or equal to 10 00126 bool is_greater_10 = false; 00127 bool is_less_1 = false; 00128 00129 // Multiply factor, for bringing the number to scientific 00130 // Notation 00131 float multiply_factor = 1.0f; 00132 00133 // Count for number of decimal moves 00134 int decimal_moves = 0; 00135 00136 // If number is exactly 0, do nothing 00137 if (num == 0) 00138 { 00139 00140 } 00141 else if (num >= 10 || num <= -10) // If the number is greater than 10 00142 { 00143 is_greater_10 = true; 00144 multiply_factor = 0.1f; 00145 } 00146 else if (num < 1 && num > -1) // If the number is less than 1 00147 { 00148 is_less_1 = false; 00149 multiply_factor = 10.0f; 00150 } // If the number is between 10 and 1, do nothing 00151 00152 // Bring number to one digit before decimal, if not already 00153 while (num >= 10 || num <= -10 || (num < 1 && num > -1 && num != 0)) 00154 { 00155 // Multiply 00156 num = num * multiply_factor; 00157 00158 // Update counter 00159 is_greater_10 ? decimal_moves++ : decimal_moves--; 00160 } 00161 00162 // Get floating point string without the E and the rest 00163 uint8_t* data = format_floating(num, dest, length, after_digits, 1); 00164 00165 // Append E and the exponent 00166 data[*length] = 'E'; 00167 int decimal_moves_original = decimal_moves; // Create copy as decimal_moves will go to 0 00168 uint8_t exp_length = 0; // Determine how long the exponent should be 00169 if (decimal_moves_original < 0) // If there is a negative exponent, we need to add 1 for the length 00170 { 00171 exp_length++; 00172 } 00173 while (decimal_moves != 0) // Add one to length for each digit 00174 { 00175 exp_length++; 00176 decimal_moves = decimal_moves / 10; 00177 } 00178 if (exp_length == 0) // If decimal moves is still 0 00179 { 00180 exp_length++; // Make exponent length one 00181 } 00182 uint8_t* exp_length_ptr = &exp_length; // Point to the number of digits in exponent 00183 format_integer(decimal_moves_original, data + *length, exp_length_ptr, exp_length); 00184 00185 // Update length and dest 00186 *length = *length + 1 + exp_length; // Add the E and the exponent to length 00187 00188 return data; // Return data 00189 } 00190 };