- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
将精度提高到 double 以上的一种方法(例如,如果我的应用程序正在做一些与空间相关的事情,需要表示许多光年距离内的准确位置)是使用 double-double ,一个由两个 double 值组成的结构,表示两者之和。算法以对这种结构的各种算术运算而闻名,例如double-double + double-double, double × double-double 等如 this paper 中所示.
(请注意,这与 IEEE 754-2008 binary128 格式不同,也就是四精度,并且不能保证往返于 double-double 和 binary128 之间的转换。)
将这种数量表示为字符串的一种明显方法是使用字符串表示 double 的每个单独组件,例如“1.0+1.0e-200”。我的问题是,是否有一种已知的方法可以将值表示为单个小数的字符串相互转换? IE。给定字符串“0.3”,然后提供最接近此表示的 double 值,或者反方向进行。一种天真的方法是使用 10 的连续乘法/除法,但这对于双数来说是不够的,所以我有点怀疑它们在这里是否有效。
最佳答案
诸如求和 2 个浮点变量之类的技术只是有效地将尾数位宽加倍,因此足以存储/加载更大的尾数。
标准 IEEE 754 double 有 52+1 位尾数导致
log10(2^53) = 15.95 = ~16 [dec digits]
所以当你添加 2 个这样的变量时:
log10(2^(53+53)) = 31.9 = ~32 [dec digits]
所以只需将 32 位尾数存储到/从字符串中加载。 2 个变量的指数相差 +/- 53,因此仅存储其中一个就足够了。
要进一步提高性能和精度,您可以使用十六进制字符串。它更快,并且没有舍入,因为您可以直接在尾数位和十六进制字符串字符之间进行转换。
任意 4 位组成一个十六进制数字所以
(53+53) / 4 = 26.5 = ~27 [hex digits]
如您所见,它的存储效率也更高,唯一的问题是指数分隔符,因为六位数字包含 E
,因此您需要通过大小写区分数字和指数分隔符或使用不同的字符或仅使用符号,例如:
1.23456789ABCDEFe10
1.23456789ABCDEFe+10
1.23456789ABCDEF|+10
1.23456789ABCDEF+10
我通常使用第一个版本。您还需要记住指数是尾数的位移,因此结果数是:
mantisa<<exponent = mantisa * (2^exponent)
现在,在从字符串加载/存储到字符串期间,您只需加载 53+53
位整数,然后将其分成 2 个尾数,并在位级别重建浮点值......重要的是您尾数对齐,所以 exp1+53 = exp2
给或取 1
...
所有这些都可以在整数算术上完成。
如果你的指数是 exp10 那么你将在存储和加载到/从字符串中对数字进行大量舍入,因为你的尾数通常会在小数点前后丢失许多零位进行转换在十进制和二进制/十六进制之间非常困难且不准确(特别是如果您将计算限制为尾数的 64/80/128/160 位
)。
这里是一个 C++ 示例(仅在整数算术上以 decadic 形式打印 32 位 float ):
//---------------------------------------------------------------------------
AnsiString f32_prn(float fx) // scientific format integers only
{
const int ms=10+5; // mantisa digits
const int es=2; // exponent digits
const int eb=100000;// 10^(es+3)
const int sz=ms+es+5;
char txt[sz],c;
int i=0,i0,i1,m,n,exp,e2,e10;
DWORD x,y,man;
for (i0=0;i0<sz;i0++) txt[i0]=' ';
// float -> DWORD
x=((DWORD*)(&fx))[0];
// sign
if (x>=0x80000000){ txt[i]='-'; i++; x&=0x7FFFFFFF; }
else { txt[i]='+'; i++; }
// exp
exp=((x>>23)&255)-127;
// man
man=x&0x007FFFFF;
if ((exp!=-127)&&(exp!=+128)) man|=0x00800000; // not zero or denormalized or Inf/NaN
// special cases
if ((man==0)&&(exp==-127)){ txt[i]='0'; i++; txt[i]=0; return txt; } // +/- zero
if ((man==0)&&(exp==+128)){ txt[i]='I'; i++;
txt[i]='N'; i++;
txt[i]='F'; i++; txt[i]=0; return txt; } // +/- Infinity
if ((man!=0)&&(exp==+128)){ txt[i]='N'; i++;
txt[i]='A'; i++;
txt[i]='N'; i++; txt[i]=0; return txt; } // +/- Not a number
// align man,exp to 4bit
e2=(1+(exp&3))&3;
man<<=e2;
exp-=e2+23; // exp of lsb of mantisa
e10=0; // decimal digits to add/remove
m=0; // mantisa digits
n=ms; // max mantisa digits
// integer part
if (exp>=-28)
{
x=man; y=0; e2=exp;
// shift x to integer part <<
if (x) for (;e2>0;)
{
while (x>0x0FFFFFFF){ y/=10; y+=((x%10)<<28)/10; x/=10; e10++; }
e2-=4; x<<=4; y<<=4;
x+=(y>>28)&15; y&=0x0FFFFFFF;
}
// shift x to integer part >>
for (;e2<0;e2+=4) x>>=4;
// no exponent?
if ((e10>0)&&(e10<=es+3)) n++; // no '.'
// print
for (i0=i;x;)
{
if (m<n){ txt[i]='0'+(x%10); i++; m++; if ((m==n)&&(x<eb)) m+=es+1; } else e10++;
x/=10;
}
// reverse digits
for (i1=i-1;i0<i1;i0++,i1--){ c=txt[i0]; txt[i0]=txt[i1]; txt[i1]=c; }
}
// fractional part
if (exp<0)
{
x=man; y=0; e2=exp;
// shift x to fractional part <<
if (x) for (;e2<-28;)
{
while ((x<=0x19999999)&&(y<=0x19999999)){ y*=10; x*=10; x+=(y>>28)&15; y&=0x0FFFFFFF; e10--; }
y>>=4; y&=0x00FFFFFF; y|=(x&15)<<24;
x>>=4; x&=0x0FFFFFFF; e2+=4;
}
// shift x to fractional part <<
for (;e2>-28;e2-=4) x<<=4;
// print
x&=0x0FFFFFFF;
if ((m)&&(!e10)) n+=es+2; // no exponent means more digits for mantisa
if (x)
{
if (m){ txt[i]='.'; i++; }
for (i0=i;x;)
{
y*=10; x*=10;
x+=(y>>28)&15;
if (m<n)
{
i0=((x>>28)&15);
if (!m)
{
if (i0)
{
txt[i]='0'+i0; i++; m++;
txt[i]='.'; i++;
}
e10--;
if (!e10) n+=es+2; // no exponent means more digits for mantisa
}
else { txt[i]='0'+i0; i++; m++; }
} else break;
y&=0x0FFFFFFF;
x&=0x0FFFFFFF;
}
}
}
else{
// no fractional part
if ((e10>0)&&(e10<sz-i))
for (;e10;e10--){ txt[i]='0'+i0; i++; m++; }
}
// exponent
if (e10)
{
if (e10>0) // move . after first digit
{
for (i0=i;i0>2;i0--) txt[i0]=txt[i0-1];
txt[2]='.'; i++; e10+=i-3;
}
// sign
txt[i]='E'; i++;
if (e10<0.0){ txt[i]='-'; i++; e10=-e10; }
else { txt[i]='+'; i++; }
// print
for (i0=i;e10;){ txt[i]='0'+(e10%10); e10/=10; i++; }
// reverse digits
for (i1=i-1;i0<i1;i0++,i1--){ c=txt[i0]; txt[i0]=txt[i1]; txt[i1]=c; }
}
txt[i]=0;
return txt;
}
//---------------------------------------------------------------------------
只需将 AnsiString
返回类型更改为您可以随意使用的任何字符串类型或 char*
...
如您所见,它包含大量代码和大量 hack,并且在内部使用了超过 24 位的尾数来降低 decadic 指数造成的舍入误差。
所以我强烈建议使用二进制指数 (exp2
) 和六位数字作为尾数,这将大大简化您的问题并完全消除舍入。唯一的问题是当你想要打印或输入 decadic 数字时,在这种情况下你别无选择,只能四舍五入......幸运的是你可以使用 hexa 输出并将其转换为 decadic on strings......或者从单变量 prints 构建 print 。 ..
有关详细信息,请参阅相关 QA:
关于algorithm - 如何在 double-double 和 decimal 字符串之间进行转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59849740/
我正在尝试将一个字符串逐个字符地复制到另一个字符串中。目的不是复制整个字符串,而是复制其中的一部分(我稍后会为此做一些条件......) 但我不知道如何使用迭代器。 你能帮帮我吗? std::stri
我想将 void 指针转换为结构引用。 结构的最小示例: #include "Interface.h" class Foo { public: Foo() : mAddress((uint
这有点烦人:我有一个 div,它从窗口的左上角开始过渡,即使它位于文档的其他任何位置。我试过 usign -webkit-transform-origin 但没有成功,也许我用错了。有人可以帮助我吗?
假设,如果将 CSS3 转换/转换/动画分配给 DOM 元素,我是否可以检测到该过程的状态? 我想这样做的原因是因为我正在寻找类似过渡链的东西,例如,在前一个过渡之后运行一个过渡。 最佳答案 我在 h
最近我遇到了“不稳定”屏幕,这很可能是由 CSS 转换引起的。事实上,它只发生在 Chrome 浏览器 上(可能还有 Safari,因为一些人也报告了它)。知道如何让它看起来光滑吗?此外,您可能会注意
我正在开发一个简单的 slider ,它使用 CSS 过渡来为幻灯片设置动画。我用一些基本样式和一些 javascript 创建了一支笔 here .注意:由于 Codepen 使用 Prefixfr
我正在使用以下代码返回 IList: public IList FindCodesByCountry(string country) { var query =
如何设计像这样的操作: 计算 转化 翻译 例如:从“EUR”转换为“CNY”金额“100”。 这是 /convert?from=EUR&to=CNY&amount=100 RESTful 吗? 最佳答
我使用 jquery 组合了一个图像滚动器,如下所示 function rotateImages(whichHolder, start) { var images = $('#' +which
如何使用 CSS (-moz-transform) 更改一个如下所示的 div: 最佳答案 你可以看看Mozilla Developer Center .甚至还有例子。 但是,在我看来,您的具体示例不
我需要帮助我正在尝试在选中和未选中的汉堡菜单上实现动画。我能够为菜单设置动画,但我不知道如何在转换为 0 时为左菜单动画设置动画 &__menu { transform: translateX(
我正在为字典格式之间的转换而苦苦挣扎:我正在尝试将下面的项目数组转换为下面的结果数组。本质上是通过在项目第一个元素中查找重复项,然后仅在第一个参数不同时才将文件添加到结果集中。 var items:[
如果我有两个定义相同的结构,那么在它们之间进行转换的最佳方式是什么? struct A { int i; float f; }; struct B { int i; float f; }; void
我编写了一个 javascript 代码,可以将视口(viewport)从一个链接滑动到另一个链接。基本上一切正常,你怎么能在那里看到http://jsfiddle.net/DruwJ/8/ 我现在的
我需要将文件上传到 meteor ,对其进行一些图像处理(必要时进行图像转换,从图像生成缩略图),然后将其存储在外部图像存储服务器(s3)中。这应该尽可能快。 您对 nodejs 图像处理库有什么建议
刚开始接触KDB+,有一些问题很难从Q for Mortals中得到。 说,这里 http://code.kx.com/wiki/JB:QforMortals2/casting_and_enumera
我在这里的一个项目中使用 JSF 1.2 和 IceFaces 1.8。 我有一个页面,它基本上是一大堆浮点数字段的大编辑网格。这是通过 inputText 实现的页面上的字段指向具有原始值的值对象
ScnMatrix4 是一个 4x4 矩阵。我的问题是什么矩阵行对应于位置(ScnVector3),旋转(ScnVector4),比例(ScnVector3)。第 4 行是空的吗? 编辑: 我玩弄了
恐怕我是 Scala 新手: 我正在尝试根据一些简单的逻辑将 Map 转换为新 Map: val postVals = Map("test" -> "testing1", "test2" -> "te
输入: This is sample 1 This is sample 2 输出: ~COLOR~[Green]This is sample 1~COLOR~[Red]This is sam
我是一名优秀的程序员,十分优秀!