Question

I'm trying to convert strings such as 5.7303333333e+02 to the decimal type. I've tried using [decimal]::TryParse but the return value is false.

Is there a method similar to [datetime]::parseexact, or any clean way to convert these strings? Or am I going to have to parse out the e+02 and do that math separately?

Was it helpful?

Solution

What about :

[int]"5.7303333333e+02"
[decimal]"5.7303333333e+02"

OTHER TIPS

TL;DR:

You need to specify NumberStyles.Float

PS C:\> $s = '5.7303333333333333333333333e+02'
PS C:\> $style = [Globalization.NumberStyles]::Float
PS C:\> $culture = [cultureinfo]::GetCultureInfo('en-US')
PS C:\> [decimal]::Parse($s, $style)
573.03333333333333333333333
PS C:\> [decimal]$dec = 0
PS C:\> [decimal]::TryParse($s, $style, $culture, [ref] $dec)
True
PS C:\> $dec
573.03333333333333333333333

or append the d suffix

PS C:\> Invoke-Expression ($s + 'd')
573.0333333333333333333333333

As Emperor XLII commented above, [decimal]"5.7303333333e+02" does not actually work because it'll convert to decimal through double. Try adding more digits and you'll immediately realized that the output isn't correct anymore:

PS C:\> Trace-Command TypeConversion { [decimal]'5.7303333333e+02' } -PSHost
DEBUG: TypeConversion Information: 0 : Converting to decimal.
DEBUG: TypeConversion Information: 0 : Exception converting to decimal: "Input string was not in a correct format.". Converting to decimal passing through double.
DEBUG: TypeConversion Information: 0 : Numeric Conversion through System.Double.
573.03333333
PS C:\> [decimal]'5.7303333333e+02'
573.03333333
PS C:\> [decimal]'5.730333333333333333333333333e+02' # doesn't work
573.033333333333
PS C:\> 5.730333333333333333333333333e+02d           # correct value
573.0333333333333333333333333

As you can see if we use the d suffix for decimal we'll get the correct high-precision value, so one simple trick is just spawning a new shell to normalize the value although that'll be obviously slow, or use Invoke-Expression

PS C:\> $d = '5.730333333333333333333333333e+02'
PS C:\> [decimal]$(powershell -com ($d + 'd'))
573.0333333333333333333333333
PS C:\> Invoke-Expression ($d + 'd'))
573.0333333333333333333333333

But why doesn't TryParse work? The reason is because the default style used by Decimal.Parse and Decimal.TryParse is like this

[ws][sign][digits,]digits[.fractional-digits][ws]

which doesn't allow the exponent. If you read Parse's documentation you'll see that the full number format is

[ws][$][sign][digits,]digits[.fractional-digits][e[sign]digits][ws]

Where

e:

  • The 'e' or 'E' character, which indicates that the value is represented in exponential notation. The s parameter can represent a number in exponential notation if style includes the NumberStyles.AllowExponent flag.

That means you need to use NumberStyles.Float (which includes NumberStyles.AllowExponent) as above to make it work

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top