我有一个用Microsoft Visual C++ 6.0编写的应用程序.现在我使用C#在Visual Studio 2010中重写了应用程序,但由于精度问题,结果不匹配.其中一个精确问题是以下问题.
float a = 1.0f;
float b = 3.0f;
float c = a / b;
Run Code Online (Sandbox Code Playgroud)
在Visual Studio 2010中运行时,这是C#代码,给出cvalue =0.333333343
但是相同的代码,在值定义中的值之后删除f,当在Visual C++ 6.0上运行时给出c值= 0.333333.
任何人都可以解决它并解释在Visual Studio和Visual C++ 6.0中获得相同c值的方法吗?
实际上,这些值来自观察窗口.我开始知道不同版本的visual studio在浮点格式表示方面可能有所不同.因此,手表中的值可能没用.这就是我在两个visual studio版本中打印值的原因,结果如下.使用visual c ++语言的visual studio 6.0,它是0.333333(六个3)
但是使用C#语言的visual studio 10它是0.3333333(七个3)
那么有人可以帮助我使我的C#程序产生与visual C++相同的结果吗?(即如何使浮动操作在两个版本上产生相同的结果???)
>>> import numpy as np
>>> from scipy import stats
>>> a = np.r_[1., 2., np.nan, 4., 5.]
>>> stats.nanmean(a)
2.9999999999999996
>>> np.nansum(a)/np.sum(~np.isnan(a))
3.0
Run Code Online (Sandbox Code Playgroud)
我知道浮点表示的局限性.只是好奇为什么更笨拙的表达似乎给出"更好"的结果.
我正在编写一些模板化代码来使用浮点数和双精度数据算法进行基准测试,以便与GPU实现进行比较.
我发现我的浮点代码速度较慢,在调查使用英特尔的Vtune放大器后,我发现g ++正在生成额外的x86指令(cvtps2pd/cvtpd2ps和unpcklps/unpcklpd),将一些中间结果从float转换为double然后再转回.此应用程序的性能下降几乎为10%.
在使用标志-Wdouble-promotion(其中BTW未包含在-Wall或-Wextra中)进行编译之后,确定g ++警告我结果正在被提升.
我将其简化为如下所示的简单测试用例.请注意,c ++代码的顺序会影响生成的代码.复合语句(T d1 = log(r)/ r;)产生警告,而分离的版本不产生(T d = log(r); d/= r;).
以下用g ++ - 4.6.3-1ubuntu5和g ++ - 4.7.3-2ubuntu1~12.04编译,结果相同.
编译标志是:
g ++ - 4.7 -O2 -Wouble-promotion -Wextra -Wall -pedantic -Werror -std = c ++ 0x test.cpp -o test
#include <cstdlib>
#include <iostream>
#include <cmath>
template <typename T>
T f()
{
T r = static_cast<T>(0.001);
// Gives no double promotion warning
T d = log(r);
d/=r;
// Promotes to double
T d1 = log(r)/r;
return d+d1;
} …Run Code Online (Sandbox Code Playgroud) 我有一个单元测试失败,Math.Tan(-PI/2)在.NET中返回错误的版本.
"预期"值取自Wolfram online(使用-Pi/2的拼写常量).在这里看看你们自己.
正如在评论中正确观察到的,tan(-pi/2)的数学结果是无穷大.但是,常数Math.PI并不能完美地表示PI,因此这是一个"接近极限"的输入.
这是代码.
double MINUS_HALF_PI = -1.570796326794896557998981734272d;
Console.WriteLine(MINUS_HALF_PI == -Math.PI/2); //just checking...
double tan = Math.Tan(MINUS_HALF_PI);
Console.WriteLine("DotNET {0:E20}", tan);
double expected = -1.633123935319534506380133589474e16;
Console.WriteLine("Wolfram {0:E20}", expected);
double off = Math.Abs(tan-expected);
Console.WriteLine(" {0:E20}", off);
Run Code Online (Sandbox Code Playgroud)
这是印刷品:
True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
5.39375188498000000000E+011
Run Code Online (Sandbox Code Playgroud)
我认为这是浮点表示的问题.
奇怪的是,Java DOES中的相同内容返回与Wolfram相同的值,直到最后一位 - 看它在Eclipse中评估.(表达式被裁剪 - 你必须相信我他们使用与MINUS_HALF_PI上面相同的常量.)

True
DotNET -1.63317787283838440000E+016
Wolfram -1.63312393531953460000E+016
Java -1.63312393531953700000E+016
Run Code Online (Sandbox Code Playgroud)
如您所见,区别在于:
~5.39 * 10^11=2.40 * 10^1这是十个数量级!
那么,为什么.NET和Java实现的差异如此之大?我希望他们都将实际的计算推迟到处理器.这个假设对于x86来说是不现实的吗?
根据要求,我尝试用Java运行 …
所以我试图理解 JavaScript 在处理大数时的行为。考虑以下(在 Firefox 和 Chrome 中测试):
console.log(9007199254740993) // 9007199254740992
console.log(9007199254740994) // 9007199254740994
console.log(9007199254740995) // 9007199254740996
console.log(9007199254740996) // 9007199254740996
console.log(9007199254740997) // 9007199254740996
console.log(9007199254740998) // 9007199254740998
console.log(9007199254740999) // 9007199254741000
Run Code Online (Sandbox Code Playgroud)
现在,我知道为什么它会输出“错误”的数字——它试图将它们转换为浮点表示,并四舍五入到最接近的可能浮点值——但我不完全确定它为什么选择这些特定的数字。我的猜测是它试图四舍五入到最接近的“偶数”数,因为 9007199254740996 可以被 4 整除而 9007199254740994 不是,它认为 9007199254740996 更“偶数”。
javascript floating-point floating-point-precision floating-point-conversion
我正在尝试编写一个函数,该函数接受一个 32 位浮点数(已从 32 位二进制字符串转换而来)并以 32 位二进制返回先前可表示的浮点数。到目前为止,我已经从二进制转换为向下浮动,但是我在理解如何找到下一个可表示的 IEEE 754 值时遇到了麻烦。你不能只减去可能的最小可表示值(000 0000 0000 0000 0000 0001)吗?另外,在找到最接近的可表示二进制值之前从 IEEE 754 转换为 Float 有什么好处(如果有的话)?
到目前为止,我只有一个将浮点数转换为简单精度 32 位二进制的函数。我会包括我的代码,但这是给学校的,所以我觉得把它放在网上/获得明确的更正和建议是不确定的。
c floating-point representation ieee-754 floating-point-precision
我的代码:
def calc_pi(acc):
pos = False
sum = 4.0
for i in range(2, acc):
if not pos:
sum -= 4.0/(2*i-1)
pos = True
else:
sum += 4.0/(2*i-1)
pos = False
return float(sum)
print(calc_pi(5000))
Run Code Online (Sandbox Code Playgroud)
当然,我正在尝试计算一个pi,超过10个后点数.但是Python似乎要回到10.有一种简单的方法可以阻止它这样做吗?像一百万个后点数字?
谢谢!
int main()
{
float x=3.4e2;
printf("%f",x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
340.000000 // It's ok.
但是如果写x=3.1234e2输出是312.339996和x=3.12345678e2输出是312.345673.
为什么输出会像这样?我想如果我写x=3.1234e2输出应该是312.340000,但实际输出是312.339996使用GCC编译器.
c floating-point floating-point-precision floating-point-conversion
是否可以使用double或float进行溢出(环绕)?如果在x86或x64硬件上达到最大(或最小)值,会发生什么?
c c++ floating-point floating-point-exceptions floating-point-precision
我的问题的简要版本是:
怎样才算"最佳实践"的决定时,浮点数
x和Math.round(x)可被视为平等的,允许从浮点运算的精度损失?
啰嗦的版本是:
我经常需要决定给定的浮点值x是否应该被视为"整数",或者更迂腐,应该"被视为整数的浮点表示".
(例如,如果n是整数,则为数学表达式
log 10(10 n)
是一种表示相同整数n的复杂方式.这是一种思维,可以说类似浮点计算的结果可以被视为"整数的表示".)
每当Math.round(x) == x评估时,决策都很容易true:在这种情况下,我们可以说x确实是(整数的浮点表示).
但是Math.round(x) == x当它评估时,测试是不确定的false.例如,
function log10(x) { return Math.log(x)/Math.LN10; }
// -> function()
x = log10(Math.pow(10, -4))
// -> -3.999999999999999
Math.round(x) == x
// -> false
Run Code Online (Sandbox Code Playgroud)
编辑:我经常看到的一个"解决方案"就是选择一些任意的容差? = 1e-6,然后进行测试Math.abs(Math.round(x) - x) < ?.我认为这样的解决方案会产生比我认为更可接受的误报.
javascript floating-point precision equality floating-point-precision