/* * Get the best mode from VBEModeInfo[] array using all factors neccessary. */ static VBEModeInfo_t FindBestVBEMode() { VBEModeInfo_t *VBEModeInfo = (VBEModeInfo_t *)BIT.Video.VBEModeInfo; // Simply find the best mode on the basis of the XRes, Yres and the BitsPerPixel. // Also, keep in mind the Monitor Preference. VBEModeInfo_t Best = VBEModeInfo[0]; // Find log 2 of Bits Per Pixel, and multiply it with the scaling factor. Best.Score = fyl2x(Best.BitsPerPixel, BPP_SCALING_FACTOR); // Find the "shortest distance" between the three scores. // NOTE: This is better than taking an average. For example, considering 400*600 as the resolution for one mode // and 500*500 for the other mode. For average, both are given same score. For "distance" the former is // preferred. Best.Score = sqrt((Best.Score * Best.Score) + (Best.XResolution * Best.XResolution) + (Best.YResolution * Best.YResolution)); // Multiply the score by the MonitorPreference. Best.Score = (int) ((float)Best.Score * Best.MonitorPreference); // Calculate the score for each mode - while side by side, finding the best mode. for(uint32_t i = 1; i < BIT.Video.VBEModeInfoN; i++) { // If the monitor preference is 0, then continue. if((int)VBEModeInfo[i].MonitorPreference == 0) { continue; } // Find log 2 of Bits Per Pixel and multiply it with the scaling factor. VBEModeInfo[i].Score = fyl2x( VBEModeInfo[i].BitsPerPixel, BPP_SCALING_FACTOR); // Find the "shortest distance" (read note above) between the three scores. VBEModeInfo[i].Score = sqrt((VBEModeInfo[i].Score * VBEModeInfo[i].Score) + (VBEModeInfo[i].XResolution * VBEModeInfo[i].XResolution) + (VBEModeInfo[i].YResolution * VBEModeInfo[i].YResolution)); VBEModeInfo[i].Score = (int)((float)VBEModeInfo[i].Score * VBEModeInfo[i].MonitorPreference); // If the score of this is greater than the best till now, // make it the best. if(VBEModeInfo[i].Score > Best.Score) { Best = VBEModeInfo[i]; } } return Best; }
floatx80 floatx80_flog10(floatx80 a) { return fyl2x(a, floatx80_log10_2); }
floatx80 floatx80_flogn(floatx80 a) { return fyl2x(a, floatx80_ln_2); }
floatx80 floatx80_flog2(floatx80 a) { return fyl2x(a, floatx80_one); }
floatx80 fyl2xp1(floatx80 a, floatx80 b) { INT32 aExp, bExp; UINT64 aSig, bSig, zSig0, zSig1, zSig2; int aSign, bSign; aSig = extractFloatx80Frac(a); aExp = extractFloatx80Exp(a); aSign = extractFloatx80Sign(a); bSig = extractFloatx80Frac(b); bExp = extractFloatx80Exp(b); bSign = extractFloatx80Sign(b); int zSign = aSign ^ bSign; if (aExp == 0x7FFF) { if ((UINT64) (aSig<<1) || ((bExp == 0x7FFF) && (UINT64) (bSig<<1))) { return propagateFloatx80NaN(a, b); } if (aSign) { invalid: float_raise(float_flag_invalid); return floatx80_default_nan; } else { if (bExp == 0) { if (bSig == 0) goto invalid; float_raise(float_flag_denormal); } return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); } } if (bExp == 0x7FFF) { if ((UINT64) (bSig<<1)) return propagateFloatx80NaN(a, b); if (aExp == 0) { if (aSig == 0) goto invalid; float_raise(float_flag_denormal); } return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); } if (aExp == 0) { if (aSig == 0) { if (bSig && (bExp == 0)) float_raise(float_flag_denormal); return packFloatx80(zSign, 0, 0); } float_raise(float_flag_denormal); normalizeFloatx80Subnormal(aSig, &aExp, &aSig); } if (bExp == 0) { if (bSig == 0) return packFloatx80(zSign, 0, 0); float_raise(float_flag_denormal); normalizeFloatx80Subnormal(bSig, &bExp, &bSig); } float_raise(float_flag_inexact); if (aSign && aExp >= 0x3FFF) return a; if (aExp >= 0x3FFC) // big argument { return fyl2x(floatx80_add(a, floatx80_one), b); } // handle tiny argument if (aExp < EXP_BIAS-70) { // first order approximation, return (a*b)/ln(2) INT32 zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE; mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2); if (0 < (INT64) zSig0) { shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); --zExp; } zExp = zExp + bExp - 0x3FFE; mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2); if (0 < (INT64) zSig0) { shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); --zExp; } return roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1); } /* ******************************** */ /* using float128 for approximation */ /* ******************************** */ shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); float128 x = packFloat128(aSign, aExp, zSig0, zSig1); x = poly_l2p1(x); return floatx80_mul(b, float128_to_floatx80(x)); }