I have 2 values that I can not get to multiply together and get the right answer. Here is my very simple code:
$data | ForEach-Object {
$newMHV = ($_.'North' * $_.'Measured Heat Value')
$_.'North BTU' = $newMHV
$_ # Output the modified row
} | Export-Csv $AFw -NoTypeInformation
The first time through the loop $_.'North'
= 1648
and $_.'Measured Heat Value'
= 1.022
$newMHV
should be 1684.xxx
. $newMVH
always shows 1648
on the first value then changes to the second value.
When I change the calculation to division, I get the correct value.
I have tried trimming the values, etc. but I cant find it. I may need to convert them to a numeric but why would it work when I divide the values?
Note: $data
is a .csv
file that I have imported.
The crucial pointer is in the comments:
Data imported from a CSV file is invariably [string]
-typed.
Thus, you must ensure that (at least) your LHS operand is of type [double]
(or another suitable numeric type) to make your calculation work as expected (PowerShell will coerce the RHS to [double]
too, as needed):
$newMHV = [double] $_.'North' * $_.'Measured Heat Value'
As for what you tried:
The *
operator also operates on strings: if the LHS is a [string]
and the RHS is / can be coerced to a number, the string is "multiplied" (duplicated) by the RHS number; that is, if the number is $n
, you get the concatenation of $n
copies of the LHS string;[1] e.g.:
# -> 'abcabc'
'abc' * 2
In your case, the RHS, '1.022'
didn't represent an integer, which means that PowerShell implicitly did the following: [int] '1.022'
- which yields 1
; therefore, your "calculation" was ultimately the equivalent of the following, which amounted to a virtual no-op:
'1648' * 1 # -> '1648'
By contrast, the /
operator operates only on numbers, so it coerces even [string]
-typed operands to a number (which may situationally be an integer data type such as [int]
or [double]
, as needed).
# -> a [double] with value 2.5 - even though both operands are *strings*
'10' / '4'
[1] It follows that if $n
is 1
, you get (an identical copy of) the string itself, and if it is 0
, you get the empty string (''
).