任何人都可以详细解释这个log2函数是如何工作的:
inline float fast_log2 (float val)
{
int * const exp_ptr = reinterpret_cast <int *> (&val);
int x = *exp_ptr;
const int log_2 = ((x >> 23) & 255) - 128;
x &= ~(255 << 23);
x += 127 << 23;
*exp_ptr = x;
val = ((-1.0f/3) * val + 2) * val - 2.0f/3; // (1)
return (val + log_2);
}
Run Code Online (Sandbox Code Playgroud) 这是一个奇怪的事(至少对我来说).此例程打印为true:
double x = 11.0;
double y = 10.0;
if (x-y == 1.0) {
// print true
} else {
// print false
}
Run Code Online (Sandbox Code Playgroud)
但是这个例程打印错误:
double x = 1.1;
double y = 1.0;
if (x-y == 0.1) {
// print true
} else {
// print false
}
Run Code Online (Sandbox Code Playgroud)
有人想解释这里发生了什么吗?我猜这与ints冒充floats的整数运算有关.此外,还有其他基地(除了10)有这个属性?
我已经着手说明何时我需要将IEEE-754单精度和双精度数字转换成带有基数的字符串10.有FXTRACT可用的指令,但它只为基数2提供指数和尾数,因为数字计算公式为:
value = (-1)^sign * 1.(mantissa) * 2^(exponent-bias)
Run Code Online (Sandbox Code Playgroud)
如果我有特定基数的对数指令,我将能够改变2 指数的基数-表达式中的偏差部分,但目前我不知道该怎么做.我也在考虑使用标准的舍入转换为整数,但它似乎无法使用,因为它不提供精确的转换.有人知道这样做的方法/基本原则是什么?请帮忙.
我终于找到了另一个解决方案(用Java编写)
{
/* handling -infinity, +infinity and NaN, returns "" if 'f' isn't one of mentioned */
String ret = "";
if ((ret = getSpecialFloats(f)).length() != 0)
return ret;
}
int num = Float.toRawIntBits(f);
int exponent = (int)(((num >> 23) & 0xFF)-127); //8bits, bias 127
int mantissa = num & 0x7FFFFF; //23bits
/* stores decimal exponent */
int decimalExponent = …Run Code Online (Sandbox Code Playgroud) string floating-point assembly ieee-754 floating-point-precision
我试图返回一个double四舍五入到两位小数的地方.我已经介入并证实,在我的所有价值观的每一步中,都是如此doubles.这是我的方法:
public double FindAzimuthAtPointK(LwdData pointKData, SurveyData stationOne, SurveyData stationTwo)
{
var deltaDepth = stationTwo.MeasuredDepth - stationOne.MeasuredDepth;
var valueG = FindValueG(pointKData, stationOne, stationTwo);
var valueH = FindValueH(pointKData, stationOne, stationTwo);
var valueY = FindValueY(stationOne, stationTwo);
var sinStationOneInclination = Math.Sin(RadianToDegreeConversion * stationOne.Inclination);
var sinStationTwoInclination = Math.Sin(RadianToDegreeConversion * stationTwo.Inclination);
var sinStationOneInclinationSquared = Math.Pow(Math.Sin(RadianToDegreeConversion * stationOne.Inclination), 2);
var sinStationTwoInclinationSquared = Math.Pow(Math.Sin(RadianToDegreeConversion * stationTwo.Inclination), 2);
var partOneBottom = ((180 * deltaDepth) * Math.Tan(RadianToDegreeConversion * (valueG*valueY) / 2)) / (Math.PI * valueY);
var …Run Code Online (Sandbox Code Playgroud) 有理数集的基数是什么?这些有理数具有与单精度IEEE-754兼容的浮点格式的精确表示?
我想执行浮点单精度加法运算
A = +无穷大(7F800000)B = - 无穷大(FF800000)
结果(A + B)是+ NAN还是-NAN?
另一个相关问题:
如果NAN通过算术运算传播,我们得到qNAN.而sNAN表示无效的异常操作.因此,上述操作将导致sNAN.我的理解是否正确?
为什么0 11110 1111111111不是0 11111 1111111111最高半精度数?
IEEE 754将1/0的结果指定为∞(无穷大).
但是,IEEE 754然后将0×∞的结果指定为NaN.
这感觉反直觉:为什么0×∞不是0?
我们可以认为1/0 =∞作为1/z的极限,因为z趋于零
我们可以认为0×∞= 0作为0×z的极限,因为z倾向于∞.
为什么IEEE标准遵循直觉1.而不是2.?
我试图用它的c ++代码测试一个simulink块,simulink块包含一些algebratic,三角函数和积分器.在我的测试过程中,从simulink块输入使用随机数生成器,输入和输出都被记录到mat文件中(使用MatIO),将由C++代码读取,输出与C++计算得到.对于仅包含代数函数的信号,结果是精确的,差值为零,对于包含三角函数的路径,差值约为10e-16.matlab社区声称他们是正确的而glibc不是.
最近我发现在glibc中实现的三角函数的输出值不等于matlabs中产生的值,根据旧问题1 2 3和我的实验,这些差异与1 glp> glibc的准确性有关.对于大多数块而言,这个10e-16误差感觉不大,但是在积分器的输出中,10e-16积累的越来越多,积分器的最终误差将是大约1e-3,这有点高,这种阻止是不可接受的.
经过对该问题的大量研究后,我决定使用其他方法来计算sin/cos函数,而不是glibc中提供的函数.
我实施了这些apporaches,
1-泰勒系列具有长双变量和-O2(强制使用x87 FPU及其80位浮点运算)
2-taylor系列与GNU quadmath库(128位精度)
3个MPFR库(128位)
4- CRLibm(正确舍入的libm)
5- Sun的LibMCR(就像CRLibm一样)
6- X86 FSIN/FCOS具有不同的舍入模式
7- Java.lang.math到JNI(我认为matlab使用)
8-fdlibm(根据我见过的一篇博文)
9- openlibm
10-通过mex/matlab引擎调用matlab函数
除了最后一个以外的实验不能生成等于matlab的值.我测试了所有这些库和方法的广泛输入,其中一些像libmcr和fdlibm将为一些输入产生NAN值(看起来他们没有良好的范围检查),其余的产生值错误10e-16及更高.与matlab相比,只有最后一个产生正确的值,但是调用matlab函数并不比本机实现快得多且慢得多.
另外我还说为什么MPFR和泰勒系列长双重和四重奏都出错了.
这是具有长双变量(80位精度)的泰勒系列,并且应该用-O2编译,这可以防止将FPU堆栈中的值存储到寄存器中(80位到64位=精度损失),在进行任何计算之前,还将设置x87的舍入模式到最近的
typedef long double dt_double;
inline void setFPUModes(){
unsigned int mode = 0b0000111111111111;
asm(
"fldcw %0;"
: : "m"(mode));
}
inline dt_double factorial(int x) //calculates the factorial
{
dt_double fact = 1;
for (; x >= 1 ; x--)
fact = x * fact;
return fact;
}
inline dt_double …Run Code Online (Sandbox Code Playgroud)