Sometimes sharing one concept in a post, allows you to share another concept in another post. That brings us to today. This is that other post.
Originally, I had a great title for this post: It was Rounding Precision Decision. Then, for whatever reason, I went and made sure that precision was the word I was after. It wasn’t. Precision is the total number of digits in a number. Scale is the number of digits after the decimal.
Last night I decided I should add a Round parameter to a function I’m writing. This would allow the user to determine how rounding should be applied to a given number. The parameter values, as I see them now, will be 0 through 4. This is to say a numerical value may have zero decimal places up to four, depending on the person/process running the function. Neat, right? Like I sometimes do, I opened Window Terminal to start some one-off testing.
Let’s start with an ordered hash table of numeric values. As you’ll see, the values will vary in the number of decimal places from zero to five.
[PS7.1.5][C:\] $Hash = [ordered]@{'Num0' = 42; 'Num1' = 42.1; 'Num2' = 42.12; 'Num3' = 42.123; 'Num4' = 42.1234; 'Num5' = 42.12345} [PS7.1.5][C:\] $Hash Name Value ---- ----- Num0 42 Num1 42.1 Num2 42.12 Num3 42.123 Num4 42.1234 Num5 42.12345 [PS7.1.5][C:\]
While we’re here, let’s loop through the keys and values in this hash table. We’ll need this construct soon enough anyway.
[PS7.1.5][C:\] Foreach ($Key in $Hash.Keys) {"$Key`: $($Hash[$Key])"} Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 [PS7.1.5][C:\]
That works. Now what we need to consider is that we’re going to need to iterate over $Hash
multiple times, so we can apply each of the decimal values, 0 – 5 for this post. This may be confusing, but the next example should help explain how we get there.
[PS7.1.5][C:\] Foreach ($Value in 0..5) {$Value} 0 1 2 3 4 5 [PS7.1.5][C:\] Foreach ($Value in 0..5) {Foreach ($Key in $Hash.Keys) {"$Key`: $($Hash[$Key])"}} Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 [PS7.1.5][C:\]
Now that we have this working, let’s apply some rounding to each of the sets of numbers. Before we do that, however, I’m heading back to VSCode. Sometimes the one-off code I write gets a bit unwieldy. For reference, we’re going to use the Round method in the System.Math
class, such as [math]::Round(<number>,<scale>
).
$Hash = [ordered]@{ 'Num0' = 42 'Num1' = 42.1 'Num2' = 42.12 'Num3' = 42.123 'Num4' = 42.1234 'Num5' = 42.12345 } Foreach ($Value in 0..5) { "Rounding to $Value" Foreach ($Key in $Hash.Keys) { "$Key`: $([math]::Round($Hash[$Key],$Value))" } # End Foreach. '--separator--' } # End Foreach. Rounding to 0 Num0: 42 Num1: 42 Num2: 42 Num3: 42 Num4: 42 Num5: 42 --separator-- Rounding to 1 Num0: 42 Num1: 42.1 Num2: 42.1 Num3: 42.1 Num4: 42.1 Num5: 42.1 --separator-- Rounding to 2 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.12 Num4: 42.12 Num5: 42.12 --separator-- Rounding to 3 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.123 Num5: 42.123 --separator-- Rounding to 4 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.1234 --separator-- Rounding to 5 Num0: 42 Num1: 42.1 Num2: 42.12 Num3: 42.123 Num4: 42.1234 Num5: 42.12345 --separator--
At first glance, this PowerShell code may look like it’s failing. Look at the “Rounding to 3” section, for instance. There are values where it appeared to round to zero, one, and two decimal places. Remember though, these numbers didn’t start with three decimals places or more. It did exactly what we asked it to do to the best of its ability. I don’t know of a way that the Round method can add zeros if we actually wanted that — let me know if you — but there’s another way!
This time, we’ll use the -f
format operator and force zeros into the decimals places. I probably won’t do this in my upcoming post, but I think it’s worth seeing, as there’s value here.
Foreach ($Value in 0..5) { "Rounding to $Value" Foreach ($Key in $Hash.Keys) { "$Key`: $("{0:N$Value}" -f $Hash[$Key])" } # End Foreach. '--separator--' } # End Foreach. Rounding to 0 Num0: 42 Num1: 42 Num2: 42 Num3: 42 Num4: 42 Num5: 42 --separator-- Rounding to 1 Num0: 42.0 Num1: 42.1 Num2: 42.1 Num3: 42.1 Num4: 42.1 Num5: 42.1 --separator-- Rounding to 2 Num0: 42.00 Num1: 42.10 Num2: 42.12 Num3: 42.12 Num4: 42.12 Num5: 42.12 --separator-- Rounding to 3 Num0: 42.000 Num1: 42.100 Num2: 42.120 Num3: 42.123 Num4: 42.123 Num5: 42.123 --separator-- Rounding to 4 Num0: 42.0000 Num1: 42.1000 Num2: 42.1200 Num3: 42.1230 Num4: 42.1234 Num5: 42.1234 --separator-- Rounding to 5 Num0: 42.00000 Num1: 42.10000 Num2: 42.12000 Num3: 42.12300 Num4: 42.12340 Num5: 42.12345 --separator--
And that’s, that. Back to the other post that inspired this one. See you there in time!