将两个"Double"变量与-eq/-ne进行比较不会验证数字是否大于2位数

Pro*_*eur 3 variables double powershell comparison equals

我试图比较两个Double变量Powershell.当变量超过2位数(不计算精度)时,相等测试意外失败.

我错过了一些明显的东西吗?

这是测试脚本输出:

PS C:\test> .\test.ps1
==========
TEST ONE
==========
Value of Double1: 336.1
Type of Double1: System.Double
-----
Value of Double2: 336.2
Type of Double2: System.Double
-----
Value of Double1+.1: 336.2
Type of Double1+.1: System.Double
-----
Does Double1 not equal Double2: True
Does Double1+.1 not equal Double2: True

==========
TEST TWO
==========

Value of Double3: 36.1
Type of Double3: System.Double
-----
Value of Double4: 36.2
Type of Double4: System.Double
-----
Value of Double3+.1: 36.2
Type of Double3+.1: System.Double
-----
Does Double3 not equal Double4: True
Does Double3+.1 not equal Double4: False
Run Code Online (Sandbox Code Playgroud)

这是测试脚本,请注意第一个测试未通过测试,我将.1添加到变量,但第二个测试通过.

##################################
# START TEST
##################################

$Double1 = 336.1
$Double2 = 336.2

write-host "=========="
write-host "TEST ONE"
write-host "=========="
write-host "Value of Double1: $Double1"
write-host "Type of Double1:" $Double1.GetType().FullName
write-host "-----"
write-host "Value of Double2: $Double2"
write-host "Type of Double2:" $Double2.GetType().FullName
write-host "-----"
write-host "Value of Double1+.1:" ($Double1+.1)
write-host "-----"
write-host "Does Double1 not equal Double2:" ($Double1 -ne $Double2)    
write-host "Does Double1+.1 not equal Double2:" (($Double1+.1) -ne $Double2)
write-host ""

write-host "=========="
write-host "TEST TWO"
write-host "=========="

$Double3 = 36.1
$Double4 = 36.2

write-host ""
write-host "Value of Double3: $Double3"
write-host "Type of Double3:" $Double3.GetType().FullName
write-host "-----"
write-host "Value of Double4: $Double4"
write-host "Type of Double4:" $Double4.GetType().FullName
write-host "-----"
write-host "Value of Double3+.1:" ($Double3+.1)
write-host "-----"
write-host "Does Double3 not equal Double4:" ($Double3 -ne $Double4)    
write-host "Does Double3+.1 not equal Double4:" (($Double3+.1) -ne $Double4)
write-host ""
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 7

请注意,这不是Powershell的问题,它只是浮​​点运算存在的问题.您可以在C#中重现相同的行为

double d = 336.1;
Console.WriteLine((d + .1) == 336.2); // False
Run Code Online (Sandbox Code Playgroud)

问题是336.1 + .1实际上并不等于336.2.您可以通过转储2个值的原始字节来证明这一点

 unsafe
 {
    double d1 = 336.1;
    double d2 = d + .1d;
    double d3 = 336.2;
    Console.WriteLine(*(long*)(&d2));
    Console.WriteLine(*(long*)(&d3));
 }
Run Code Online (Sandbox Code Playgroud)

打印

4644622109139743540
4644622109139743539
Run Code Online (Sandbox Code Playgroud)

请注意,最后2个字节关闭了1个值.至于为什么会出现这种情况的人更需要处理浮点运算.通常,在比较浮点值时应该小心.而不是严格的平等,最好检查它们是否在特定范围内

if (Math.Abs(d2 - d3) <= .01)) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这也不是.NET的问题.任何使用浮点数的代码都存在问题,例如使用IEEE 754的任何语言. (3认同)
  • 336.1的最准确表示是3.36100000000000022737367544323E2.0.1为1.00000000000000005551115123126E-1.因此,当你在代码中看到0.1并且它是双重记住它实际上不是那个精确的值而只是一个近似值.有关更多信息,请访问http://www.binaryconvert.com/.因此,Joey说这是对实数的二进制表示的FINITE(有限位数)的限制. (3认同)
  • 任何以.1结尾的基数10都是坏的,因为十分之一是转换为二进制时的重复值,就像转换为十进制时的三分之一一样. (2认同)