Line data Source code
1 : /* Copyright (c) 2005, Dmitry Xmelkov 2 : All rights reserved. 3 : 4 : Rewritten in C by Soren Kuula 5 : 6 : Redistribution and use in source and binary forms, with or without 7 : modification, are permitted provided that the following conditions are met: 8 : 9 : * Redistributions of source code must retain the above copyright 10 : notice, this list of conditions and the following disclaimer. 11 : * Redistributions in binary form must reproduce the above copyright 12 : notice, this list of conditions and the following disclaimer in 13 : the documentation and/or other materials provided with the 14 : distribution. 15 : * Neither the name of the copyright holders nor the names of 16 : contributors may be used to endorse or promote products derived 17 : from this software without specific prior written permission. 18 : 19 : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 : ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 : LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 : CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 : SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 : INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 : CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 : ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 : POSSIBILITY OF SUCH DAMAGE. */ 30 : 31 : #include <stdint.h> 32 : #include "xtoa_fast.h" 33 : 34 1209606 : char * ultoa_invert (uint32_t val, char *s, uint8_t base) { 35 1209606 : if (base == 8) { 36 : do { 37 8 : *s++ = '0' + (val & 0x7); 38 8 : val >>= 3; 39 8 : } while(val); 40 4 : return s; 41 : } 42 : 43 1209602 : if (base == 16) { 44 : do { 45 26114 : uint8_t digit = '0' + (val & 0xf); 46 : #if XTOA_UPPER == 0 47 : if (digit > '0' + 9) 48 : digit += ('a' - '0' - 10); 49 : #else 50 26114 : if (digit > '0' + 9) 51 2403 : digit += ('A' - '0' - 10); 52 : #endif 53 26114 : *s++ = digit; 54 26114 : val >>= 4; 55 26114 : } while(val); 56 15130 : return s; 57 : } 58 : 59 : // Every base which in not hex and not oct is considered decimal. 60 : 61 : // 33 bits would have been enough. 62 1194472 : uint64_t xval = val; 63 : do { 64 3366972 : uint8_t saved = xval; 65 3366972 : xval &= ~1; 66 3366972 : xval += 2; 67 3366972 : xval += xval >> 1; // *1.5 68 3366972 : xval += xval >> 4; // *1.0625 69 3366972 : xval += xval >> 8; // *1.00390625 70 3366972 : xval += xval >> 16; // *1.000015259 71 3366972 : xval += xval >> 32; // it all amounts to *1.6 72 3366972 : xval >>= 4; // /16 ... so *1.6/16 is /10, fraction truncated. 73 3366972 : *s++ = '0' + saved - 10 * (uint8_t)xval; 74 3366972 : } while (xval); 75 1194472 : return s; 76 : } 77 : 78 : 79 18 : char * ulltoa_invert (uint64_t val, char *s, uint8_t base) { 80 18 : if (base == 8) { 81 : do { 82 0 : *s++ = '0' + (val & 0x7); 83 0 : val >>= 3; 84 0 : } while(val); 85 0 : return s; 86 : } 87 : 88 18 : if (base == 16) { 89 : do { 90 30 : uint8_t digit = '0' + (val & 0xf); 91 : #if XTOA_UPPER == 0 92 : if (digit > '0' + 9) 93 : digit += ('a' - '0' - 10); 94 : #else 95 30 : if (digit > '0' + 9) 96 12 : digit += ('A' - '0' - 10); 97 : #endif 98 30 : *s++ = digit; 99 30 : val >>= 4; 100 30 : } while(val); 101 2 : return s; 102 : } 103 : 104 : // Every base which in not hex and not oct is considered decimal. 105 : 106 : // 64 bits is not actually enough, we need 65, but it should 107 : // be good enough for the log dumping we're using this for 108 16 : uint64_t xval = val; 109 : do { 110 76 : uint8_t saved = xval; 111 76 : xval &= ~1; 112 76 : xval += 2; 113 76 : xval += xval >> 1; // *1.5 114 76 : xval += xval >> 4; // *1.0625 115 76 : xval += xval >> 8; // *1.00390625 116 76 : xval += xval >> 16; // *1.000015259 117 76 : xval += xval >> 32; // it all amounts to *1.6 118 76 : xval >>= 4; // /16 ... so *1.6/16 is /10, fraction truncated. 119 76 : *s++ = '0' + saved - 10 * (uint8_t)xval; 120 76 : } while (xval); 121 16 : return s; 122 : } 123 :