0.4 - 0.3 - 0.1 is equal to zero but is true only for Perl6 ?! why PS not return the correct result...and python ?!!
PS> 0.4 - 0.3 - 0.1 -eq 0
False
PS> 0.4 - 0.3 - 0.1
2.77555756156289E-17
PS> perl6
> 0.4 - 0.3 - 0.1 == 0
True
> 0.4 - 0.3 - 0.1
0
PS> python
>>> 0.4 - 0.3 - 0.1 == 0
False
>>> 0.4 - 0.3 - 0.1
2.7755575615628914e-17
0
2.77555756156289E-17
> $PSVersionTable
Name Value
---- -----
PSVersion 6.1.0
PSEdition Core
GitCommitId 6.1.0
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Common problem with floating-point arithmetic.
Computers don't typically represent numbers in true base 10 that we're accustomed to. It's to inefficient to keep track of and usually not significant enough to worry about. They use binary floating-point numbers to approximate a large number space without wasting a ton of memory on the value.
This isn't really the place to talk about it in full, but there are plenty of proper write-ups on the Internet, if you want to look one up. Suffice it to say that, just like how in base 10 we have a huge issue neatly representing the value of 1/3 in decimal notation (0.33333... going on forever), computers have a huge issue properly representing some more "normal" (to us) fractions in their typical base 2 numerals. They only have finite decimal places, so if we give them a number they cannot completely represent (due to it having infinitely repeating digits in base 2) the value they give us back will not be completely accurate.
In PowerShell, at least, you can use decimal numerals instead to use a more "accurate" depiction of the value:
PS> 0.4d - 0.3d - 0.1d
0.0
This takes up more memory and the slight differences aren't typically worth the extra memory to worry about. The value you get back with the standard floating point calculation is not zero, but is for many intents and purposes more or less the same.
Brief depiction of why this is an issue:
0.4 = 4/10 = 2/5
in base 2:
10/101 = 0.01001001... (repeating forever)
A number we can represent with 0.4 in base 10 has infinite digits in binary.
As this article explains it seems Perl 6 evades this topic by internally working with rational numbers by splitting them up into numerator and denominator. This would mean that it needs to keep track of twice the amount of numbers in memory, but it gains the ability to more accurately reflect fractional numbers.
PowerShell is built on .NET Core, and as far as I'm aware there is no such type present in Core. We could make one, I'm sure, but it may or may not be worth it. As I mention -- we have decimal for things like this, really.
Most helpful comment
Brief depiction of why this is an issue:
A number we can represent with
0.4in base 10 has infinite digits in binary.As this article explains it seems Perl 6 evades this topic by internally working with rational numbers by splitting them up into numerator and denominator. This would mean that it needs to keep track of twice the amount of numbers in memory, but it gains the ability to more accurately reflect fractional numbers.
PowerShell is built on .NET Core, and as far as I'm aware there is no such type present in Core. We could make one, I'm sure, but it may or may not be worth it. As I mention -- we have
decimalfor things like this, really.