>>> float(str(0.65000000000000002))
0.65000000000000002
>>> float(str(0.47000000000000003))
0.46999999999999997 ???
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?如何转换0.47000000000000003为字符串并将结果值恢复为浮点数?
我在Windows上使用Python 2.5.4.
我想知道我是否可以假设在相同的64位浮点数上的相同操作在任何现代PC和大多数常见编程语言中给出完全相同的结果?(C++,Java,C#等).我们可以假设,我们正在对数字进行操作,结果也是一个数字(没有NaN,INF等等).
我知道使用浮点数(IEEE 854-1987和IEEE 754-2008)有两种非常类似的计算标准.但是我不知道它在实践中是怎么回事.
我正在维护一个程序,该程序从PDP-11(模拟!)程序中获取数据并将其置于基于Windows的现代系统中.我们遇到的问题是某些数据值被报告为"1.#QNAN"以及"1.#QNB".客户最近透露,PDP-11程序中的"坏"值由2个16位字表示,除第一个之外设置了所有位.我认为,当我们尝试将这些转换为IEEE浮点数时,我们会得到错误.
我发现下面的代码用于将PDP-11值转换为IEEE.我对浮点表示的复杂性并不是很了解,但这对我来说似乎有点简单!这是否真的可靠地将PDP-11浮标转换为IEEE?
// ---------------------------------------------------------------- cnvPDPfloat
// CNVPDPFLOAT
// ----------------------------------------------------------------------------
//
// Converts PDP11 float (two 16-bit words) into IEEE float
//
// PDP11 and IEEE floats have same layout so can be mapped onto eachother.
// But PDP11 exponent must have 2 subtracted for IEEE. Or just divide by 4.
//
float cnvPDPfloat( PDP11Float input )
{
union
{
unsigned long pdp11;
float ieee;
} uFloat;
uFloat.pdp11 = (input.word[0] << 16) + input.word[1];
return (uFloat.ieee / (float) 4.0);
}
Run Code Online (Sandbox Code Playgroud)
--- …
有谁知道一个JavaScript库,它准确地实现了32位浮点值的IEEE 754规范?我问,因为我正在尝试用JavaScript编写交叉编译器,并且由于源语言有严格要求浮点值符合IEEE 754,因此生成的JavaScript代码也必须这样做.这意味着我必须能够获得32位浮点数的加法,减法,乘法和除法的正确IEEE 754值.不幸的是,标准的JavaScript Number类型是一个64位的双倍,它会得到与我期望的不同的结果.该项目确实必须使用JavaScript,这是我尚未完成的唯一主要绊脚石.
我也遇到了64位长的问题.
ECMAScript规范Math.pow具有以下特殊规则:
- 如果x <0且x是有限的且y是有限的并且y不是整数,则结果是NaN.
(http://es5.github.com/#x15.8.2.13)
结果Math.pow(-8, 1 / 3)给出NaN而不是-2
这条规则的原因是什么?是否存在某种更广泛的计算机科学或IEEE推理这一规则的原因,或者它只是TC39/Eich曾经做过的选择?
感谢Amadan与我的交流,我想我现在明白了这个推理.为了后代,我想扩大我们的讨论范围.
我们来看下面的例子:尽管它确实应该是Math.pow(823543, 1 / 7)收益率.这是由必须首先转换为十进制表示的事实引入的不准确性,该十进制表示被截断并且失去精度.当我们处理正数时,这不是一个很糟糕的问题,因为我们仍然得到一个非常接近实际结果的结果.6.99999999999999971 / 70.14285714285714285
然而,一旦我们踏入负面世界,我们就会遇到问题.如果一个JavaScript引擎试图计算Math.pow(-823543, 1 / 7)它,首先需要转换1 / 7为十进制,所以它实际上是计算Math.pow(-823543, 0.14285714285714285)实际上没有真正的答案.在这种情况下,它可能必须返回,NaN因为它找不到实数,即使真正的答案应该是-7.此外,寻找接近实数的复数来做出"最佳猜测"可能涉及一定程度的复杂性,他们不希望JS引擎在数学领域中拥有.
我的猜测是由于考虑到浮点数的精度损失导致他们遵循以下规则:非整数幂的负数应该总是NaN- 基本上因为非整数幂可能给出一个由于精度损失导致的复数,即使它不应该,也可能没有好的方法可以从中恢复.
有了这个,我相当满意,但我确实欢迎进一步的信息.
我想知道你是否可以帮助解释将整数转换为float或float转换为整数的过程.对于我的课程,我们只使用按位运算符来完成此操作,但我认为从类型到类型的强制理解将在这个阶段帮助我更多.
根据我目前所知,对于int要浮动,你必须将整数转换为二进制,通过查找有效数,指数和分数来规范化整数的值,然后从那里输出浮点值?
至于float到int,你必须将值分成有效数,指数和分数,然后反转上面的指令得到一个int值?
我试着按照这个问题的说明:在C中将float转换为int(按位)
但我真的不能理解它.
另外,有人可以解释为什么在将int转换为float时大于23位的值需要舍入?
提前致谢
我正在将一些程序从Matlab移植到C++以提高效率.重要的是两个程序的输出完全相同(**).
我对此操作面临不同的结果:
std::sin(0.497418836818383950) = 0.477158760259608410 (C++)
sin(0.497418836818383950) = 0.47715876025960846000 (Matlab)
N[Sin[0.497418836818383950], 20] = 0.477158760259608433 (Mathematica)
Run Code Online (Sandbox Code Playgroud)
所以,据我所知,C++和Matlab都使用IEEE754定义的双算术.我想我已经阅读过IEEE754在最后一位允许不同结果的地方.使用mathematica来决定,似乎C++更接近于结果.如何强制Matlab精确计算包含最后一位的sin,以便结果相同?
在我的程序中,这种行为会导致很大的错误,因为数值微分方程求解器在最后一位不断增加这个错误.但是我不确定C++移植版本是否正确.我猜测即使IEEE754允许最后一位不同,在某种程度上保证在更多IEEE754定义的双重操作中使用结果时这个错误不会变得更大(因为否则,根据IEEE754标准,两个不同的程序可以产生完全不同的输出).所以另一个问题是我是对的吗?
我想得到两个粗体问题的答案.编辑:第一个问题是相当有争议的,但不太重要,有人可以评论第二个问题吗?
注意:这不是打印中的错误,以防您想要检查,这是我获得这些结果的方式:
http://i.imgur.com/cy5ToYy.png
注意(**):我的意思是最终输出,它是一些计算的结果,显示一些带有4位小数的实数,需要完全相同.我在问题中谈到的错误变得更大(因为更多的操作,每一个在Matlab和C++中都是不同的)所以最终的差异是巨大的)(如果你很好奇,看看差异如何开始变大,这里是完整输出[很快链接],但这与问题无关)
在GCC上,我们可以-ffast-math加速浮点计算.但是当我们依赖于NaN和Inf浮点值的正确行为时,我们也会打开-fno-finite-math-only,因此假设值不是NaN/Inf的优化
对于MSVC来说,-ffast-math显然是"等同" /fp:fast.但是,与GCC一样-ffast-math,它还包括假设Nan/Inf不存在的优化.(重要的是,似乎测试像std :: isnan()不能保证给出"准确"的结果.)
是否有一个MSVC C++编译选项,它允许您利用大多数/fp:fast优化,但仍然"正确"处理NaN和Inf值?(或者至少,保证像std :: isnan()/ std :: isinf()这样的测试会检测NaN/Inf,如果它们恰好被生成了.)
该文档在这篇文章的标题的说法说:
float_precision:string,默认无
指定C引擎应该将哪个转换器用于浮点值.选项有没有对于普通转换器,高的高精度转换器,以及round_trip用于往返转换器.
我想更多地了解所提到的三种算法,最好不必深入研究源代码1.
问:这些算法是否具有我可以谷歌的名称,以准确了解他们做了什么以及他们有何不同?
(另外,还有一个问题:在这种情况下究竟是什么"C引擎"?这是Pandas特定的东西,还是Python范围的东西?以上都没有?)
1不熟悉有问题的代码库,我希望找到相关的源代码需要很长时间.但即使假设我设法找到它,我对这种算法的体验是它们的实现是如此高度优化,并且在如此低的水平,没有一些高级描述,至少对我来说,真的很难跟着发生了什么.
我使用的是Microchip的XC32编译器,它基于标准的C编译器.
我正在从RS485网络上的设备读取32位值并将其存储在unsigned long中,我将其命名为DWORD.
即
typedef DWORD unsigned long;
Run Code Online (Sandbox Code Playgroud)
就目前而言,当我将此值转换为float时,我得到的值基本上是它的整数表示的浮点版本,而不是正确的IEEE-754解释浮点数.
即
DWORD dword_value = readValueOnRS485();
float temp = (float)dword_value;
Run Code Online (Sandbox Code Playgroud)
这里,dword_value将以十六进制格式表示为0x4366C0C4,作为十进制将表示为1130807492,因此对浮点数的类型转换只是给我1.130807492*10 ^ 9或1130807492.0这不是我想要的.
我想要单精度IEEE-754表示,它给我一个浮点值230.75299072265625
显然,对浮动进行类型转换对我来说不起作用.我需要一种可以转换此形式的方法.我在XC32库中看了一遍,但找不到任何东西.
有没有人知道一个预定义的方法,为我正确地做出这种解释?或者可能有一些建议的方法我可以写?我试图避免为这个特定任务编写自己的代码,因为我担心如果C已经有了这个功能,我找不到有效的解决方案.
有趣的是,如果我对char*执行此操作,则该值将在char*上正确表示为230.75:
sprintf(random_char_pointer, "%.2f, dword_value);
Run Code Online (Sandbox Code Playgroud)
在这里打印random_char_pointer到屏幕给我230.75所以sprintf必须正确处理解释.因此我假设C中已经存在某些东西.有人可以帮忙吗?
ieee-754 ×10
c++ ×2
javascript ×2
python ×2
64-bit ×1
algorithm ×1
arm ×1
assembly ×1
c ×1
ecma262 ×1
ecmascript-5 ×1
long-integer ×1
matlab ×1
pandas ×1
point ×1
portability ×1
precision ×1
string ×1
visual-c++ ×1