为什么这个浮点计算给出不同机器上的不同的结果? [英] Why does this floating-point calculation give different results on different machines?
问题描述
我有一个简单的常规,其计算从一个浮点值的纵横比。因此对于值1.77777779,程序返回字符串16:9。我有我的机器上测试了这一点,它工作正常。
I have a simple routine which calculates the aspect ratio from a floating point value. So for the value 1.77777779, the routine returns the string "16:9". I have tested this on my machine and it works fine.
该例程被给定为:
public string AspectRatioAsString(float f)
{
bool carryon = true;
int index = 0;
double roundedUpValue = 0;
while (carryon)
{
index++;
float upper = index * f;
roundedUpValue = Math.Ceiling(upper);
if (roundedUpValue - upper <= (double)0.1 || index > 20)
{
carryon = false;
}
}
return roundedUpValue + ":" + index;
}
现在另一台机器上,我得到完全不同的结果。所以,我的机器上,1.77777779给。16:9,而另一台机器上我得到38:21
Now on another machine, I get completely different results. So on my machine, 1.77777779 gives "16:9" but on another machine I get "38:21".
推荐答案
这里的C#specifiction的一个有趣的一点,从第4.1.6节:
Here's an interesting bit of the C# specifiction, from section 4.1.6:
浮点运算可能
具有较高的precision进行比
结果类型的操作。对于
例如,某些硬件结构
支持扩展或长双
浮点类型具有更大的范围
和precision比double类型,
并隐式执行所有
使用这种浮点运算
更高的precision类型。只有在
在性能上能有这样成本过高
硬件架构中,以制成
执行浮点运算与
少precision,而非
需要实施没收
性能和precision,C#
允许有较高的precision类型为
用于所有浮点
操作。除了提供更多
precise的结果,这种情况很少有什么
可测量的效果。
Floating-point operations may be performed with higher precision than the result type of the operation. For example, some hardware architectures support an "extended" or "long double" floating-point type with greater range and precision than the double type, and implicitly perform all floating-point operations using this higher precision type. Only at excessive cost in performance can such hardware architectures be made to perform floating-point operations with less precision, and rather than require an implementation to forfeit both performance and precision, C# allows a higher precision type to be used for all floating-point operations. Other than delivering more precise results, this rarely has any measurable effects.
这是可能的,这是对可衡量效果多亏了呼叫天花板之一。数量级的九级以浮点数字的上限,正如其他人所指出的,放大的0.000000002一个区别,因为事实证明15.99999999为16个和16.00000001为17.操作前大量不同事后略有不同的两个数字;微小的差异可能的事实,不同的机器可以在其浮点运算或多或少都有额外precision来解释。
It is possible that this is one of the "measurable effects" thanks to that call to Ceiling. Taking the ceiling of a floating point number, as others have noted, magnifies a difference of 0.000000002 by nine orders of magnitude because it turns 15.99999999 into 16 and 16.00000001 into 17. Two numbers that differ slightly before the operation differ massively afterwards; the tiny difference might be accounted for by the fact that different machines can have more or less "extra precision" in their floating point operations.
相关问题:
-
<一个href=\"http://stackoverflow.com/questions/2345534/c-xna-visual-studio-difference-between-release-and-debug-modes/2345645#2345645\">http://stackoverflow.com/questions/2345534/c-xna-visual-studio-difference-between-release-and-debug-modes/2345645#2345645
<一个href=\"http://stackoverflow.com/questions/2225503\">http://stackoverflow.com/questions/2225503
要解决您如何计算从一个浮动的纵横比具体的问题:我想可能是解决这个问题的方式完全不同。我会做一个表是这样的:
To address your specific problem of how to compute an aspect ratio from a float: I'd possibly solve this a completely different way. I'd make a table like this:
struct Ratio
{
public int X { get; private set; }
public int Y { get; private set; }
public Ratio (int x, int y) : this()
{
this.X = x;
this.Y = y;
}
public double AsDouble() { return (double)X / (double)Y; }
}
Ratio[] commonRatios = {
new Ratio(16, 9),
new Ratio(4, 3),
// ... and so on, maybe the few hundred most common ratios here.
// since you are pinning results to be less than 20, there cannot possibly
// be more than a few hundred.
};
现在你的代码是
public string AspectRatioAsString(double ratio)
{
var results = from commonRatio in commonRatios
select new {
Ratio = commonRatio,
Diff = Math.Abs(ratio - commonRatio.AsDouble())};
var smallestResult = results.Min(x=>x.Diff);
return String.Format("{0}:{1}", smallestResult.Ratio.X, smallestResult.Ratio.Y);
}
注意code现在如何读取非常像您要执行的操作:从普通比率的这个列表中,选择一个中给定的比例和普通比例之间的差异最小化。
Notice how the code now reads very much like the operation you are trying to perform: from this list of common ratios, choose the one where the difference between the given ratio and the common ratio is minimized.
这篇关于为什么这个浮点计算给出不同机器上的不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!