我可以说使用double(或float)代替以下三个优点decimal:
但这些优势似乎只适用于计算密集型操作,例如建模软件中的操作.当然,在需要精确度时,不应使用双精度数,例如财务计算.那么有没有任何实际的理由选择double(或float)而不是decimal"正常"的应用程序?
编辑补充:感谢所有伟大的回应,我向他们学习.
还有一个问题:一些人认为双打可以更精确地代表实数.宣布时,我认为他们通常也会更准确地代表他们.但是,当执行浮点运算时,准确度是否会降低(有时是显着的)是真实的说法吗?
我知道你不能正常依赖双重或十进制类型值之间的相等,但我想知道0是否是特殊情况.
虽然我可以理解0.00000000000001和0.00000000000002之间的不精确,但0本身似乎很难搞砸,因为它什么都没有.如果你对什么都不精确,那就不再是什么了.
但我对这个话题知之甚少,所以我不能说.
double x = 0.0;
return (x == 0.0) ? true : false;
Run Code Online (Sandbox Code Playgroud)
这会永远回归真实吗?
所以我试图弄清楚为什么模运算符返回如此大的异常值.
如果我有代码:
double result = 1.0d % 0.1d;
它会给出一个结果0.09999999999999995.我期望值的价值0
注意使用除法运算符不存在此问题 -
double result = 1.0d / 0.1d;
将给出结果10.0,意味着剩下的应该是0.
让我明确一点:对于存在错误我并不感到惊讶,我很惊讶这个错误与游戏中的数字相比非常大.0.0999~ = 0.1和0.1处于相同数量级0.1d并且仅相差一个数量级1.0d.它不像你可以将它与double.epsilon相比,或者说"如果它的<0.00001差异则相等".
我已经在StackOverflow上阅读了这个主题,在下面的帖子中有 两 三个,其中包括.
任何人都可以建议解释为什么这个错误如此之大?任何建议,以避免将来遇到问题(我知道我可以使用十进制,但我担心它的性能).
编辑:我应该特别指出,我知道0.1是一个无限重复的二进制数字系列 - 这与它有什么关系吗?
在Release模式和debug模式下运行时,我们有一些单元测试失败.如果我在发布模式下附加调试器,则测试通过.有太多的代码要在这里发布,所以我真的只是在寻找调试发布模式问题的最佳实践.我检查过:
解决方案:在这种情况下,这是因为我在比较浮点变量是否相等.如果没有重大的重构,我无法将浮点数更改为十进制,所以我添加了一个扩展方法:
public static class FloatExtension
{
public static bool AlmostEquals(this float f1, float f2, float precision)
{
return (Math.Abs(f1 - f2) <= precision);
}
public static bool AlmostEquals(this float f1, float f2)
{
return AlmostEquals(f1, f2, .00001f);
}
public static bool AlmostEquals(this float? f1, float? f2)
{
if (f1.HasValue && f2.HasValue)
{
return AlmostEquals(f1.Value, f2.Value);
}
else if (f1 == null && f2 == null)
{
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud) 我惊讶地发现System.Numerics.Complex.NET中的数据类型不会产生数学上准确的结果.
Complex.Sqrt(-1) != Complex.ImaginaryOne
Run Code Online (Sandbox Code Playgroud)
而不是(0,1),我得到(6.12303176911189E-17,1),看起来很像舍入错误.
现在我意识到浮点运算有时会导致这样的结果,但通常使用整数将避免舍入误差.
为什么这个看似基本的操作会产生明显错误的结果?
在C#中,有一个名为decimal(System.Decimal结构)的类型.我找到的信息显示它比某些情况更好float和double类型:
Borland C++ Builder程序有类似的类型吗?
这是一个简单的代码,显示我认为处理双数时的错误...
double wtf = 36.76662445068359375000;
id xxx = [NSDecimalNumber numberWithDouble: wtf];
NSString *myBug = [xxx stringValue];
NSLog(@"%.20f", wtf);
NSLog(@"%@", myBug);
NSLog(@"-------\n");
Run Code Online (Sandbox Code Playgroud)
终端将显示两个不同的号码
36.76662445068359375000和
36.76662445068359168
这是一个错误还是我错过了什么?
如果第二个数字被舍入,那是一个非常奇怪的四舍五入...
= = = = = = = = = =
我正在编辑原始问题以包含一个WTF错误...
试试这个:
修改原始数字并在10位十进制数字上截断...所以......
double wtf = 36.76662445068359375000;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:10];
NSString *valueX = [formatter stringFromNumber:[NSDecimalNumber numberWithDouble:wtf]];
[formatter release];
NSLog(@"%@", valueX);
Run Code Online (Sandbox Code Playgroud)
现在的答案是36.7666244507
现在该值是一个包含10位十进制数字的字符串...现在让我们将其转换回double
double myDoubleAgain = [valueX doubleValue];
NSLog(@"%.20f", myDoubleAgain);
Run Code Online (Sandbox Code Playgroud)
答案是36.76662445070000018177 ??????
myDoubleAgain现在有更多的数字!!!!
这是我的测试代码:
Dim testSingle As Single = 7.2
Dim testSingleF As Single = 7.2F
Dim testDouble As Double = 7.2
If testSingle = testDouble Then ' this is false
Label1.Text = "true"
Else
Label1.Text = "false"
End If
If testSingleF = testDouble Then ' this is false
Label2.Text = "true"
Else
Label2.Text = "false"
End If
If testSingle = 7.2F Then ' this is true
Label3.Text = "true"
Else
Label3.Text = "false"
End If
Run Code Online (Sandbox Code Playgroud)
正如您在我的评论中所看到的,前两个陈述是错误的,第三个是真的.这是为什么?精度应该无关紧要,因为它的数量很少.
这里发生了什么?
这是代码:
static void Main(string[] args)
{
int xd2 = 5;
for (double xd = (double)xd2; xd <= 6; xd += 0.01)
{
Console.WriteLine(xd);
}
}
Run Code Online (Sandbox Code Playgroud)
这是输出:

我想继续添加0.01(正如你在屏幕上看到的,有时恰好添加0.99999)谢谢
可能是一个简单的问题,但这个计算困扰我..为什么double test = 57.05 - 57等于0.049999999999997158而不是0.05?我应该使用哪种数据类型来获得正确的结果?
可能重复:
.NET上的双精度问题
Double计算产生奇数结果
我知道双重价值的内部代表0.2是类似的0.199999.但是下面的代码仍然让我感到困惑.
码:
public static void main(String[] args) {
double d= 0.3d;
double f= 0.1d;
System.out.println(d+f);
System.out.println(d*f);
System.out.println(d);
System.out.println(f);
System.out.println(d-f);
System.out.println(d/f);
System.out.println((d-f)*(d-f));
}
Run Code Online (Sandbox Code Playgroud)
OUTPUT:
0.4
0.03
0.3
0.1
0.19999999999999998
2.9999999999999996
0.039999999999999994
Run Code Online (Sandbox Code Playgroud)
实际上发生了什么?加法,乘法顺利,但减法,除法不是.任何人都可以详细说明为什么加法与减法不同?