// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Provides fixed - point logarithm operations .
*
* Copyright ( C ) 2006 Christoph Pfister ( christophpfister @ gmail . com )
*/
#include <linux/bitops.h>
#include <linux/export.h>
#include <linux/int_log.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm /bug.h>
static const unsigned short logtable[256 ] = {
0 x0000, 0 x0171, 0 x02e0, 0 x044e, 0 x05ba, 0 x0725, 0 x088e, 0 x09f7,
0 x0b5d, 0 x0cc3, 0 x0e27, 0 x0f8a, 0 x10eb, 0 x124b, 0 x13aa, 0 x1508,
0 x1664, 0 x17bf, 0 x1919, 0 x1a71, 0 x1bc8, 0 x1d1e, 0 x1e73, 0 x1fc6,
0 x2119, 0 x226a, 0 x23ba, 0 x2508, 0 x2656, 0 x27a2, 0 x28ed, 0 x2a37,
0 x2b80, 0 x2cc8, 0 x2e0f, 0 x2f54, 0 x3098, 0 x31dc, 0 x331e, 0 x345f,
0 x359f, 0 x36de, 0 x381b, 0 x3958, 0 x3a94, 0 x3bce, 0 x3d08, 0 x3e41,
0 x3f78, 0 x40af, 0 x41e4, 0 x4319, 0 x444c, 0 x457f, 0 x46b0, 0 x47e1,
0 x4910, 0 x4a3f, 0 x4b6c, 0 x4c99, 0 x4dc5, 0 x4eef, 0 x5019, 0 x5142,
0 x526a, 0 x5391, 0 x54b7, 0 x55dc, 0 x5700, 0 x5824, 0 x5946, 0 x5a68,
0 x5b89, 0 x5ca8, 0 x5dc7, 0 x5ee5, 0 x6003, 0 x611f, 0 x623a, 0 x6355,
0 x646f, 0 x6588, 0 x66a0, 0 x67b7, 0 x68ce, 0 x69e4, 0 x6af8, 0 x6c0c,
0 x6d20, 0 x6e32, 0 x6f44, 0 x7055, 0 x7165, 0 x7274, 0 x7383, 0 x7490,
0 x759d, 0 x76aa, 0 x77b5, 0 x78c0, 0 x79ca, 0 x7ad3, 0 x7bdb, 0 x7ce3,
0 x7dea, 0 x7ef0, 0 x7ff6, 0 x80fb, 0 x81ff, 0 x8302, 0 x8405, 0 x8507,
0 x8608, 0 x8709, 0 x8809, 0 x8908, 0 x8a06, 0 x8b04, 0 x8c01, 0 x8cfe,
0 x8dfa, 0 x8ef5, 0 x8fef, 0 x90e9, 0 x91e2, 0 x92db, 0 x93d2, 0 x94ca,
0 x95c0, 0 x96b6, 0 x97ab, 0 x98a0, 0 x9994, 0 x9a87, 0 x9b7a, 0 x9c6c,
0 x9d5e, 0 x9e4f, 0 x9f3f, 0 xa02e, 0 xa11e, 0 xa20c, 0 xa2fa, 0 xa3e7,
0 xa4d4, 0 xa5c0, 0 xa6ab, 0 xa796, 0 xa881, 0 xa96a, 0 xaa53, 0 xab3c,
0 xac24, 0 xad0c, 0 xadf2, 0 xaed9, 0 xafbe, 0 xb0a4, 0 xb188, 0 xb26c,
0 xb350, 0 xb433, 0 xb515, 0 xb5f7, 0 xb6d9, 0 xb7ba, 0 xb89a, 0 xb97a,
0 xba59, 0 xbb38, 0 xbc16, 0 xbcf4, 0 xbdd1, 0 xbead, 0 xbf8a, 0 xc065,
0 xc140, 0 xc21b, 0 xc2f5, 0 xc3cf, 0 xc4a8, 0 xc580, 0 xc658, 0 xc730,
0 xc807, 0 xc8de, 0 xc9b4, 0 xca8a, 0 xcb5f, 0 xcc34, 0 xcd08, 0 xcddc,
0 xceaf, 0 xcf82, 0 xd054, 0 xd126, 0 xd1f7, 0 xd2c8, 0 xd399, 0 xd469,
0 xd538, 0 xd607, 0 xd6d6, 0 xd7a4, 0 xd872, 0 xd93f, 0 xda0c, 0 xdad9,
0 xdba5, 0 xdc70, 0 xdd3b, 0 xde06, 0 xded0, 0 xdf9a, 0 xe063, 0 xe12c,
0 xe1f5, 0 xe2bd, 0 xe385, 0 xe44c, 0 xe513, 0 xe5d9, 0 xe69f, 0 xe765,
0 xe82a, 0 xe8ef, 0 xe9b3, 0 xea77, 0 xeb3b, 0 xebfe, 0 xecc1, 0 xed83,
0 xee45, 0 xef06, 0 xefc8, 0 xf088, 0 xf149, 0 xf209, 0 xf2c8, 0 xf387,
0 xf446, 0 xf505, 0 xf5c3, 0 xf680, 0 xf73e, 0 xf7fb, 0 xf8b7, 0 xf973,
0 xfa2f, 0 xfaea, 0 xfba5, 0 xfc60, 0 xfd1a, 0 xfdd4, 0 xfe8e, 0 xff47,
};
unsigned int intlog2(u32 value)
{
/**
* returns : log2 ( value ) * 2 ^ 24
* wrong result if value = 0 ( log2 ( 0 ) is undefined )
*/
unsigned int msb;
unsigned int logentry;
unsigned int significand;
unsigned int interpolation;
if (unlikely(value == 0 )) {
WARN_ON(1 );
return 0 ;
}
/* first detect the msb (count begins at 0) */
msb = fls(value) - 1 ;
/**
* now we use a logtable after the following method :
*
* log2 ( 2 ^ x * y ) * 2 ^ 24 = x * 2 ^ 24 + log2 ( y ) * 2 ^ 24
* where x = msb and therefore 1 < = y < 2
* first y is determined by shifting the value left
* so that msb is bit 31
* 0 x00231f56 - > 0 x8C7D5800
* the result is y * 2 ^ 31 - > " significand "
* then the highest 9 bits are used for a table lookup
* the highest bit is discarded because it ' s always set
* the highest nine bits in our example are 100011000
* so we would use the entry 0 x18
*/
significand = value << (31 - msb);
logentry = (significand >> 23 ) % ARRAY_SIZE(logtable);
/**
* last step we do is interpolation because of the
* limitations of the log table the error is that part of
* the significand which isn ' t used for lookup then we
* compute the ratio between the error and the next table entry
* and interpolate it between the log table entry used and the
* next one the biggest error possible is 0 x7fffff
* ( in our example it ' s 0 x7D5800 )
* needed value for next table entry is 0 x800000
* so the interpolation is
* ( error / 0 x800000 ) * ( logtable_next - logtable_current )
* in the implementation the division is moved to the end for
* better accuracy there is also an overflow correction if
* logtable_next is 256
*/
interpolation = ((significand & 0 x7fffff) *
((logtable[(logentry + 1 ) % ARRAY_SIZE(logtable)] -
logtable[logentry]) & 0 xffff)) >> 15 ;
/* now we return the result */
return ((msb << 24 ) + (logtable[logentry] << 8 ) + interpolation);
}
EXPORT_SYMBOL(intlog2);
unsigned int intlog10(u32 value)
{
/**
* returns : log10 ( value ) * 2 ^ 24
* wrong result if value = 0 ( log10 ( 0 ) is undefined )
*/
u64 log;
if (unlikely(value == 0 )) {
WARN_ON(1 );
return 0 ;
}
log = intlog2(value);
/**
* we use the following method :
* log10 ( x ) = log2 ( x ) * log10 ( 2 )
*/
return (log * 646456993 ) >> 31 ;
}
EXPORT_SYMBOL(intlog10);
Messung V0.5 in Prozent C=94 H=92 G=92
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland