/*---------------------------------------------------------------------------* Project: Horizon File: math_Arithmetic.cpp Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 46347 $ *---------------------------------------------------------------------------*/ #include #include #include namespace nn { namespace math { namespace { //---- Table of exponential functions struct ExpTbl { f32 exp_val; f32 exp_delta; }; struct ExpTbl sExpTbl[32+1] = { { 0.500000000f, 0.022136891f }, // Exp(-0.693147181) = Exp(ln2 * (-16)/16) { 0.522136891f, 0.023116975f }, // Exp(-0.649825482) = Exp(ln2 * (-15)/16) { 0.545253866f, 0.024140451f }, // Exp(-0.606503783) { 0.569394317f, 0.025209240f }, // Exp(-0.563182084) { 0.594603558f, 0.026325349f }, // Exp(-0.519860385) { 0.620928906f, 0.027490871f }, // Exp(-0.476538687) { 0.648419777f, 0.028707996f }, // Exp(-0.433216988) { 0.677127773f, 0.029979008f }, // Exp(-0.389895289) { 0.707106781f, 0.031306292f }, // Exp(-0.346573590) { 0.738413073f, 0.032692340f }, // Exp(-0.303251891) { 0.771105413f, 0.034139753f }, // Exp(-0.259930193) { 0.805245166f, 0.035651249f }, // Exp(-0.216608494) { 0.840896415f, 0.037229665f }, // Exp(-0.173286795) { 0.878126080f, 0.038877963f }, // Exp(-0.129965096) { 0.917004043f, 0.040599237f }, // Exp(-0.086643398) { 0.957603281f, 0.042396719f }, // Exp(-0.043321699) = Exp(ln2 * (-1)/16) { 1.000000000f, 0.044273782f }, // Exp(0.000000000) = Exp(ln2 * (0)/16) { 1.044273782f, 0.046233950f }, // Exp(0.043321699) = Exp(ln2 * (1)/16) { 1.090507733f, 0.048280902f }, // Exp(0.086643398) { 1.138788635f, 0.050418480f }, // Exp(0.129965096) { 1.189207115f, 0.052650697f }, // Exp(0.173286795) { 1.241857812f, 0.054981743f }, // Exp(0.216608494) { 1.296839555f, 0.057415992f }, // Exp(0.259930193) { 1.354255547f, 0.059958015f }, // Exp(0.303251891) { 1.414213562f, 0.062612584f }, // Exp(0.346573590) { 1.476826146f, 0.065384679f }, // Exp(0.389895289) { 1.542210825f, 0.068279507f }, // Exp(0.433216988) { 1.610490332f, 0.071302499f }, // Exp(0.476538687) { 1.681792831f, 0.074459330f }, // Exp(0.519860385) { 1.756252160f, 0.077755926f }, // Exp(0.563182084) { 1.834008086f, 0.081198475f }, // Exp(0.606503783) { 1.915206561f, 0.084793439f }, // Exp(0.649825482) = Exp(ln2 * 15/16) { 2.000000000f, 0.088547565f }, // Exp(0.693147181) = Exp(ln2 * 16/16) }; //---- Logarithmic function table struct LogTbl { f32 log_val; f32 log_delta; }; struct LogTbl sLogTbl[256+1] = { { 0.000000000f, 0.003898640f }, // Log(1.00000000) { 0.003898640f, 0.003883500f }, // Log(1.00390625) { 0.007782140f, 0.003868477f }, // Log(1.00781250) { 0.011650617f, 0.003853569f }, // Log(1.01171875) { 0.015504187f, 0.003838776f }, // Log(1.01562500) { 0.019342963f, 0.003824096f }, // Log(1.01953125) { 0.023167059f, 0.003809528f }, // Log(1.02343750) { 0.026976588f, 0.003795071f }, // Log(1.02734375) { 0.030771659f, 0.003780723f }, // Log(1.03125000) { 0.034552382f, 0.003766483f }, // Log(1.03515625) { 0.038318864f, 0.003752350f }, // Log(1.03906250) { 0.042071214f, 0.003738322f }, // Log(1.04296875) { 0.045809536f, 0.003724399f }, // Log(1.04687500) { 0.049533935f, 0.003710579f }, // Log(1.05078125) { 0.053244515f, 0.003696862f }, // Log(1.05468750) { 0.056941376f, 0.003683245f }, // Log(1.05859375) { 0.060624622f, 0.003669729f }, // Log(1.06250000) { 0.064294351f, 0.003656311f }, // Log(1.06640625) { 0.067950662f, 0.003642991f }, // Log(1.07031250) { 0.071593653f, 0.003629768f }, // Log(1.07421875) { 0.075223421f, 0.003616640f }, // Log(1.07812500) { 0.078840062f, 0.003603608f }, // Log(1.08203125) { 0.082443669f, 0.003590668f }, // Log(1.08593750) { 0.086034337f, 0.003577821f }, // Log(1.08984375) { 0.089612159f, 0.003565066f }, // Log(1.09375000) { 0.093177225f, 0.003552402f }, // Log(1.09765625) { 0.096729626f, 0.003539827f }, // Log(1.10156250) { 0.100269453f, 0.003527341f }, // Log(1.10546875) { 0.103796794f, 0.003514942f }, // Log(1.10937500) { 0.107311736f, 0.003502631f }, // Log(1.11328125) { 0.110814366f, 0.003490405f }, // Log(1.11718750) { 0.114304771f, 0.003478264f }, // Log(1.12109375) { 0.117783036f, 0.003466208f }, // Log(1.12500000) { 0.121249244f, 0.003454235f }, // Log(1.12890625) { 0.124703479f, 0.003442344f }, // Log(1.13281250) { 0.128145823f, 0.003430535f }, // Log(1.13671875) { 0.131576358f, 0.003418807f }, // Log(1.14062500) { 0.134995165f, 0.003407158f }, // Log(1.14453125) { 0.138402323f, 0.003395589f }, // Log(1.14843750) { 0.141797912f, 0.003384098f }, // Log(1.15234375) { 0.145182010f, 0.003372684f }, // Log(1.15625000) { 0.148554694f, 0.003361348f }, // Log(1.16015625) { 0.151916042f, 0.003350087f }, // Log(1.16406250) { 0.155266129f, 0.003338901f }, // Log(1.16796875) { 0.158605030f, 0.003327790f }, // Log(1.17187500) { 0.161932820f, 0.003316753f }, // Log(1.17578125) { 0.165249573f, 0.003305788f }, // Log(1.17968750) { 0.168555361f, 0.003294896f }, // Log(1.18359375) { 0.171850257f, 0.003284075f }, // Log(1.18750000) { 0.175134332f, 0.003273325f }, // Log(1.19140625) { 0.178407657f, 0.003262646f }, // Log(1.19531250) { 0.181670303f, 0.003252035f }, // Log(1.19921875) { 0.184922338f, 0.003241494f }, // Log(1.20312500) { 0.188163832f, 0.003231021f }, // Log(1.20703125) { 0.191394853f, 0.003220615f }, // Log(1.21093750) { 0.194615468f, 0.003210276f }, // Log(1.21484375) { 0.197825743f, 0.003200003f }, // Log(1.21875000) { 0.201025746f, 0.003189795f }, // Log(1.22265625) { 0.204215541f, 0.003179653f }, // Log(1.22656250) { 0.207395194f, 0.003169575f }, // Log(1.23046875) { 0.210564769f, 0.003159560f }, // Log(1.23437500) { 0.213724329f, 0.003149609f }, // Log(1.23828125) { 0.216873938f, 0.003139720f }, // Log(1.24218750) { 0.220013658f, 0.003129893f }, // Log(1.24609375) { 0.223143551f, 0.003120127f }, // Log(1.25000000) { 0.226263679f, 0.003110422f }, // Log(1.25390625) { 0.229374101f, 0.003100778f }, // Log(1.25781250) { 0.232474879f, 0.003091193f }, // Log(1.26171875) { 0.235566071f, 0.003081667f }, // Log(1.26562500) { 0.238647738f, 0.003072199f }, // Log(1.26953125) { 0.241719937f, 0.003062790f }, // Log(1.27343750) { 0.244782726f, 0.003053437f }, // Log(1.27734375) { 0.247836164f, 0.003044142f }, // Log(1.28125000) { 0.250880306f, 0.003034904f }, // Log(1.28515625) { 0.253915210f, 0.003025721f }, // Log(1.28906250) { 0.256940931f, 0.003016594f }, // Log(1.29296875) { 0.259957524f, 0.003007521f }, // Log(1.29687500) { 0.262965046f, 0.002998503f }, // Log(1.30078125) { 0.265963548f, 0.002989539f }, // Log(1.30468750) { 0.268953087f, 0.002980628f }, // Log(1.30859375) { 0.271933715f, 0.002971770f }, // Log(1.31250000) { 0.274905486f, 0.002962965f }, // Log(1.31640625) { 0.277868451f, 0.002954212f }, // Log(1.32031250) { 0.280822663f, 0.002945510f }, // Log(1.32421875) { 0.283768173f, 0.002936860f }, // Log(1.32812500) { 0.286705033f, 0.002928260f }, // Log(1.33203125) { 0.289633293f, 0.002919710f }, // Log(1.33593750) { 0.292553003f, 0.002911210f }, // Log(1.33984375) { 0.295464213f, 0.002902760f }, // Log(1.34375000) { 0.298366973f, 0.002894358f }, // Log(1.34765625) { 0.301261331f, 0.002886005f }, // Log(1.35156250) { 0.304147335f, 0.002877700f }, // Log(1.35546875) { 0.307025035f, 0.002869442f }, // Log(1.35937500) { 0.309894478f, 0.002861232f }, // Log(1.36328125) { 0.312755710f, 0.002853069f }, // Log(1.36718750) { 0.315608779f, 0.002844952f }, // Log(1.37109375) { 0.318453731f, 0.002836881f }, // Log(1.37500000) { 0.321290612f, 0.002828856f }, // Log(1.37890625) { 0.324119469f, 0.002820876f }, // Log(1.38281250) { 0.326940345f, 0.002812941f }, // Log(1.38671875) { 0.329753286f, 0.002805051f }, // Log(1.39062500) { 0.332558337f, 0.002797205f }, // Log(1.39453125) { 0.335355542f, 0.002789402f }, // Log(1.39843750) { 0.338144944f, 0.002781643f }, // Log(1.40234375) { 0.340926587f, 0.002773927f }, // Log(1.40625000) { 0.343700514f, 0.002766253f }, // Log(1.41015625) { 0.346466767f, 0.002758622f }, // Log(1.41406250) { 0.349225390f, 0.002751033f }, // Log(1.41796875) { 0.351976423f, 0.002743486f }, // Log(1.42187500) { 0.354719909f, 0.002735980f }, // Log(1.42578125) { 0.357455889f, 0.002728515f }, // Log(1.42968750) { 0.360184404f, 0.002721090f }, // Log(1.43359375) { 0.362905494f, 0.002713706f }, // Log(1.43750000) { 0.365619200f, 0.002706362f }, // Log(1.44140625) { 0.368325561f, 0.002699057f }, // Log(1.44531250) { 0.371024618f, 0.002691792f }, // Log(1.44921875) { 0.373716410f, 0.002684565f }, // Log(1.45312500) { 0.376400975f, 0.002677378f }, // Log(1.45703125) { 0.379078353f, 0.002670229f }, // Log(1.46093750) { 0.381748581f, 0.002663117f }, // Log(1.46484375) { 0.384411699f, 0.002656044f }, // Log(1.46875000) { 0.387067743f, 0.002649008f }, // Log(1.47265625) { 0.389716751f, 0.002642009f }, // Log(1.47656250) { 0.392358761f, 0.002635048f }, // Log(1.48046875) { 0.394993808f, 0.002628122f }, // Log(1.48437500) { 0.397621931f, 0.002621233f }, // Log(1.48828125) { 0.400243164f, 0.002614381f }, // Log(1.49218750) { 0.402857545f, 0.002607563f }, // Log(1.49609375) { 0.405465108f, 0.002600782f }, // Log(1.50000000) { 0.408065890f, 0.002594035f }, // Log(1.50390625) { 0.410659925f, 0.002587324f }, // Log(1.50781250) { 0.413247249f, 0.002580647f }, // Log(1.51171875) { 0.415827895f, 0.002574004f }, // Log(1.51562500) { 0.418401899f, 0.002567396f }, // Log(1.51953125) { 0.420969295f, 0.002560821f }, // Log(1.52343750) { 0.423530116f, 0.002554280f }, // Log(1.52734375) { 0.426084395f, 0.002547772f }, // Log(1.53125000) { 0.428632167f, 0.002541297f }, // Log(1.53515625) { 0.431173465f, 0.002534856f }, // Log(1.53906250) { 0.433708320f, 0.002528446f }, // Log(1.54296875) { 0.436236767f, 0.002522069f }, // Log(1.54687500) { 0.438758836f, 0.002515725f }, // Log(1.55078125) { 0.441274561f, 0.002509412f }, // Log(1.55468750) { 0.443783972f, 0.002503130f }, // Log(1.55859375) { 0.446287103f, 0.002496880f }, // Log(1.56250000) { 0.448783983f, 0.002490661f }, // Log(1.56640625) { 0.451274644f, 0.002484473f }, // Log(1.57031250) { 0.453759117f, 0.002478316f }, // Log(1.57421875) { 0.456237433f, 0.002472189f }, // Log(1.57812500) { 0.458709623f, 0.002466092f }, // Log(1.58203125) { 0.461175715f, 0.002460026f }, // Log(1.58593750) { 0.463635741f, 0.002453989f }, // Log(1.58984375) { 0.466089730f, 0.002447982f }, // Log(1.59375000) { 0.468537712f, 0.002442004f }, // Log(1.59765625) { 0.470979715f, 0.002436055f }, // Log(1.60156250) { 0.473415770f, 0.002430135f }, // Log(1.60546875) { 0.475845905f, 0.002424244f }, // Log(1.60937500) { 0.478270148f, 0.002418381f }, // Log(1.61328125) { 0.480688529f, 0.002412546f }, // Log(1.61718750) { 0.483101076f, 0.002406740f }, // Log(1.62109375) { 0.485507816f, 0.002400962f }, // Log(1.62500000) { 0.487908777f, 0.002395211f }, // Log(1.62890625) { 0.490303988f, 0.002389487f }, // Log(1.63281250) { 0.492693475f, 0.002383791f }, // Log(1.63671875) { 0.495077267f, 0.002378122f }, // Log(1.64062500) { 0.497455389f, 0.002372480f }, // Log(1.64453125) { 0.499827870f, 0.002366865f }, // Log(1.64843750) { 0.502194735f, 0.002361276f }, // Log(1.65234375) { 0.504556011f, 0.002355714f }, // Log(1.65625000) { 0.506911724f, 0.002350177f }, // Log(1.66015625) { 0.509261902f, 0.002344667f }, // Log(1.66406250) { 0.511606569f, 0.002339182f }, // Log(1.66796875) { 0.513945751f, 0.002333723f }, // Log(1.67187500) { 0.516279474f, 0.002328290f }, // Log(1.67578125) { 0.518607764f, 0.002322881f }, // Log(1.67968750) { 0.520930646f, 0.002317498f }, // Log(1.68359375) { 0.523248144f, 0.002312140f }, // Log(1.68750000) { 0.525560284f, 0.002306806f }, // Log(1.69140625) { 0.527867090f, 0.002301497f }, // Log(1.69531250) { 0.530168587f, 0.002296212f }, // Log(1.69921875) { 0.532464799f, 0.002290952f }, // Log(1.70312500) { 0.534755751f, 0.002285715f }, // Log(1.70703125) { 0.537041466f, 0.002280503f }, // Log(1.71093750) { 0.539321969f, 0.002275314f }, // Log(1.71484375) { 0.541597282f, 0.002270149f }, // Log(1.71875000) { 0.543867431f, 0.002265007f }, // Log(1.72265625) { 0.546132438f, 0.002259888f }, // Log(1.72656250) { 0.548392326f, 0.002254792f }, // Log(1.73046875) { 0.550647118f, 0.002249720f }, // Log(1.73437500) { 0.552896838f, 0.002244670f }, // Log(1.73828125) { 0.555141508f, 0.002239643f }, // Log(1.74218750) { 0.557381150f, 0.002234638f }, // Log(1.74609375) { 0.559615788f, 0.002229655f }, // Log(1.75000000) { 0.561845443f, 0.002224695f }, // Log(1.75390625) { 0.564070138f, 0.002219757f }, // Log(1.75781250) { 0.566289895f, 0.002214840f }, // Log(1.76171875) { 0.568504735f, 0.002209946f }, // Log(1.76562500) { 0.570714681f, 0.002205073f }, // Log(1.76953125) { 0.572919754f, 0.002200221f }, // Log(1.77343750) { 0.575119974f, 0.002195391f }, // Log(1.77734375) { 0.577315365f, 0.002190581f }, // Log(1.78125000) { 0.579505946f, 0.002185793f }, // Log(1.78515625) { 0.581691740f, 0.002181026f }, // Log(1.78906250) { 0.583872766f, 0.002176279f }, // Log(1.79296875) { 0.586049045f, 0.002171554f }, // Log(1.79687500) { 0.588220599f, 0.002166848f }, // Log(1.80078125) { 0.590387447f, 0.002162163f }, // Log(1.80468750) { 0.592549610f, 0.002157498f }, // Log(1.80859375) { 0.594707108f, 0.002152853f }, // Log(1.81250000) { 0.596859961f, 0.002148229f }, // Log(1.81640625) { 0.599008190f, 0.002143624f }, // Log(1.82031250) { 0.601151813f, 0.002139038f }, // Log(1.82421875) { 0.603290851f, 0.002134473f }, // Log(1.82812500) { 0.605425324f, 0.002129926f }, // Log(1.83203125) { 0.607555250f, 0.002125399f }, // Log(1.83593750) { 0.609680650f, 0.002120892f }, // Log(1.83984375) { 0.611801541f, 0.002116403f }, // Log(1.84375000) { 0.613917944f, 0.002111933f }, // Log(1.84765625) { 0.616029877f, 0.002107482f }, // Log(1.85156250) { 0.618137360f, 0.002103050f }, // Log(1.85546875) { 0.620240410f, 0.002098637f }, // Log(1.85937500) { 0.622339046f, 0.002094242f }, // Log(1.86328125) { 0.624433288f, 0.002089865f }, // Log(1.86718750) { 0.626523153f, 0.002085506f }, // Log(1.87109375) { 0.628608659f, 0.002081166f }, // Log(1.87500000) { 0.630689826f, 0.002076844f }, // Log(1.87890625) { 0.632766670f, 0.002072540f }, // Log(1.88281250) { 0.634839209f, 0.002068253f }, // Log(1.88671875) { 0.636907462f, 0.002063984f }, // Log(1.89062500) { 0.638971446f, 0.002059733f }, // Log(1.89453125) { 0.641031179f, 0.002055499f }, // Log(1.89843750) { 0.643086679f, 0.002051283f }, // Log(1.90234375) { 0.645137961f, 0.002047084f }, // Log(1.90625000) { 0.647185045f, 0.002042902f }, // Log(1.91015625) { 0.649227947f, 0.002038737f }, // Log(1.91406250) { 0.651266683f, 0.002034589f }, // Log(1.91796875) { 0.653301272f, 0.002030458f }, // Log(1.92187500) { 0.655331730f, 0.002026343f }, // Log(1.92578125) { 0.657358073f, 0.002022245f }, // Log(1.92968750) { 0.659380318f, 0.002018164f }, // Log(1.93359375) { 0.661398482f, 0.002014099f }, // Log(1.93750000) { 0.663412582f, 0.002010051f }, // Log(1.94140625) { 0.665422633f, 0.002006019f }, // Log(1.94531250) { 0.667428651f, 0.002002003f }, // Log(1.94921875) { 0.669430654f, 0.001998003f }, // Log(1.95312500) { 0.671428657f, 0.001994019f }, // Log(1.95703125) { 0.673422675f, 0.001990050f }, // Log(1.96093750) { 0.675412726f, 0.001986098f }, // Log(1.96484375) { 0.677398824f, 0.001982161f }, // Log(1.96875000) { 0.679380985f, 0.001978240f }, // Log(1.97265625) { 0.681359225f, 0.001974334f }, // Log(1.97656250) { 0.683333559f, 0.001970444f }, // Log(1.98046875) { 0.685304003f, 0.001966569f }, // Log(1.98437500) { 0.687270572f, 0.001962709f }, // Log(1.98828125) { 0.689233281f, 0.001958864f }, // Log(1.99218750) { 0.691192146f, 0.001955035f }, // Log(1.99609375) { 0.693147181f, 0.001951220f }, // Log(2.00000000) }; /*!--------------------------------------------------------------------------* Name: FExpLn2 *---------------------------------------------------------------------------*/ NN_MATH_INLINE f32 FExpLn2(f32 x) { f32 fidx; u16 idx; f32 r; // |x| must be less than ln2 // map [-ln2, ln2) -> [0, 32) fidx = (x + F_LN2) * (32 / (2 * F_LN2)); idx = F32ToU16(fidx); r = fidx - U16ToF32(idx); return sExpTbl[idx].exp_val + r * sExpTbl[idx].exp_delta; } /*!--------------------------------------------------------------------------* Name: FLog1_2 *---------------------------------------------------------------------------*/ NN_MATH_INLINE f32 FLog1_2(f32 x) { f32 fidx; u16 idx; f32 r; // Make sure that 1 <= x < 2 // map [1, 2) -> [0, 256) fidx = (x - 1) * 256.f; // 0 <= fidx < 256 idx = F32ToU16(fidx); r = fidx - U16ToF32(idx); return sLogTbl[idx].log_val + r * sLogTbl[idx].log_delta; } } // End of anonymous namespace namespace internal { /*!--------------------------------------------------------------------------* Name: FExp *---------------------------------------------------------------------------*/ // Divide by 2^16 from -10 to 10, including both ends, and calculate the error at each sample point. // For sExpTbl[32] Maximum relative error for std is 0.0235 % Average relative error is 0.0156 % // For sExpTbl[256] Maximum relative error for std is 0.000427 % Average relative error is 0.000245 % f32 FExp(f32 x) { /* exp(x) = exp(xn + k * ln2) = exp(xn) * exp(k * ln2) = exp(xn) * 2^k |xn| ln2 */ s16 k; f32 kf; f32 xn; f32 expxn; // Converts x to the form xn + k * ln2 // However, |xn| < ln2, and k is an integer // Make sure that -128 <= k <= 127 k = F32ToS16(F_INVLN2 * x); kf = S16ToF32(k); xn = x - kf * F_LN2; // Finds exp(xn) by table lookup. expxn = FExpLn2(xn); // exp(x) = exp(xn) * 2^k // Add directly to exponent // Since the exp result will not be negative, mask the carry part and erase. u32 expx = (F32AsU32(expxn) + (k << 23)) & 0x7FFFFFFF; return U32AsF32(expx); } /*!--------------------------------------------------------------------------* Name: FLog *---------------------------------------------------------------------------*/ // Divide by 2^16 from 0.001 to 10, including both ends, and calculate the error at each sample point. // For sLogTbl[32] Maximum relative error for std is 1.528 % Average relative error is 0.00857 % // For sLogTbl[128] Maximum relative error for std is 0.386 % Average relative error is 0.000623 % // For sLogTbl[256] Maximum relative error for std is 0.192 % Average relative error is 0.000167 % // The relative error is maximized around x = 1. f32 FLog(f32 x) { /* log(x) = log(xn * 2^k) = log(xn) + log(2^k) = log(xn) + k * ln2 1 xn 2 */ s32 k; f32 kf; f32 xn; f32 logxn; // Converts x to the form xn * 2^k k = FGetExpPart(x); xn = FGetMantPart(x); kf = S16ToF32(static_cast(k)); // Finds log(xn) by table lookup. logxn = FLog1_2(xn); // log(x) = log(xn) + k * ln2 return logxn + kf * F_LN2; } } // end of namespace internal /*!--------------------------------------------------------------------------* Name: Bezier *---------------------------------------------------------------------------*/ f32 Bezier(f32 p1, f32 p2, f32 p3, f32 p4, f32 s) { // Be sure to use a better method of calculation f32 t = 1.f - s; f32 tt = t * t; f32 ss = s * s; f32 a1 = tt * t; f32 a2 = tt * s * 3.f; f32 a3 = ss * t * 3.f; f32 a4 = ss * s; return a1*p1 + a2*p2 + a3*p3 + a4*p4; } /*!--------------------------------------------------------------------------* Name: CatmullRom *---------------------------------------------------------------------------*/ f32 CatmullRom(f32 p0, f32 p1, f32 p2, f32 p3, f32 s) { // Be sure to use a better method of calculation return Hermite(p1, 0.5f * (p0 + p2), p2, 0.5f * (p1 + p3), s); } /*!--------------------------------------------------------------------------* Name: CntBit1 *---------------------------------------------------------------------------*/ u32 CntBit1(u32 x) { x = x - ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; x = x + (x >> 8); x = x + (x >> 16); return x & 0x0000003f; } /*!--------------------------------------------------------------------------* Name: CntBit1 *---------------------------------------------------------------------------*/ u32 CntBit1(const u32* first, const u32* last) { const u32 n = u32(last - first); u32 i, j, lim; unsigned int s = 0; unsigned int ss, x; for (i = 0; i < n; i += 31) { lim = (n < i + 31) ? n : (i + 31); ss = 0; for (j = i; j < lim; ++j) { x = *(first + j); x -= ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; ss += x; } x = (ss & 0x00ff00ff) + ((ss >> 8) & 0x00ff00ff); x = (x & 0x0000ffff) + (x >> 16); s += x; } return s; } /*!--------------------------------------------------------------------------* Name: DistBit *---------------------------------------------------------------------------*/ u32 DistBit(const u32* first1, const u32* last1, const u32* first2) { unsigned int n = 0; while(first1 != last1) { n += DistBit(*first1, *first2); ++first1; ++first2; } return n; } /*!--------------------------------------------------------------------------* Name: RevBit *---------------------------------------------------------------------------*/ u32 RevBit(u32 x) { x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555); x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333); x = ((x & 0x0f0f0f0f) << 4) | ((x >> 4) & 0x0f0f0f0f); x = (x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24); return x; } /*!--------------------------------------------------------------------------* Name: IExp *---------------------------------------------------------------------------*/ int IExp(int x, u32 n) { int p, y; y = 1; p = x; for (;;) { if (n & 1) { y *= p; } n >>= 1; if (n == 0) { return y; } p *= p; } } /*!--------------------------------------------------------------------------* Name: ILog10 *---------------------------------------------------------------------------*/ u32 ILog10(u32 x) { u32 y; static u32 table2[11] = { 0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, 0xFFFFFFFF }; y = (19 * (31 - CntLz(x))) >> 6; y += ((table2[y + 1] - x) >> 31); return y; } namespace internal { /*!--------------------------------------------------------------------------* Name: CntLz_ *---------------------------------------------------------------------------*/ u32 CntLz_(u32 x) { unsigned int y; int n, c; n = 32; c = 16; do { y = x >> c; if (y != 0) { n -= c; x = y; } c >>= 1; } while(c != 0); return n - x; } } // internal }} // nw::math